jest와 typeorm, typedi

Ssookveloper·2021년 4월 24일
0

TIL-or-오늘의삽질

목록 보기
2/2

회사에서 새로운 프로젝트를 시작하는데
테스트 코드를 작성하면서 개발을 진행해보면 어떨까 싶어서
jest를 이용한 테스트 코드를 작성해보기로 했다.

쉬울 줄 알았는데 무작정 진행해서인지 생각보다 엄청난 삽질을 했다...

프로젝트 구조는 클래스 기반의
컨트롤러, 서비스, 리포지토리로 구성되어있다.(routing-controllers 사용해보려고 함!)
클래스의 의존성 주입을 위해 typedi를 사용하고있다.

test폴더를 생성하고 sample.spec.ts라는 테스트 코드를 작성할 파일을 만든다.
jest라이브러리를 설치하고 init하면 생성되는 jest.config.js파일에

// sample.spec.ts

module.exports= {
  ...
  testRegex: '.spec.ts$',
  ...
}

위와 같이 작성하여 .spec.ts의 파일명을 가진 파일들을 테스트코드에 사용한다고 알려준다.

1. DB연결

가장 먼저 헤맸던 거는 db연결이다.
db에 접근해 데이터를 가져와 테스트를 진행해야하는데
beforeAll()에서 테스트를 진행하기전에 연결을 해줘야한다.

// sample.spec.ts

import { User } from '../entities/User';

beforeAll(async () => {
  await createConnection({
    type: 'sqlite',
    database: ':memory:',
    dropSchema: true,
    entities: [User],
    synchronize: true,
    logging: false,
  });
});

와 같이 작성하여 db연결을 진행해주었다.
실제 db는 mysql을 사용하지만 테스트에서 간단하게 사용하기위해 sqlite를 사용했고,
:memory:는 휘발성db라는 것을 의미해준다.
entities에는 entity들이 위치한 파일 경로를 작성해주는 레퍼런스가 많았는데
경로를 잘못 작성해서인지 잘 안되길래 그냥 import해와서 배열에 넣어주었다.

2. 테스트 코드 작성

처음에는 간단한 테스트를 위하여

// sample.sepc.ts 
import { UserService } from '../services/UserService';
...
describe('User', () => {
  it('test', async () => {
    const users: User[] = await UserService.getUsers();
    expect(users.length).toBe(0);
  });
});

와 같이 작성했는데 자꾸

Property 'getUsers' does not exist on type 'typeof UserService'.ts(2339)

라는 에러가 나왔다.

3. typedi를 통한 의존성 관리

typedi의 @Service를 작성해서 의존성주입을 해주고 있었는데
저거는 그냥 클래스일뿐이라 사용을 할 수 없는 것 같았다.
(@Service 데코레이터를 이용해 아래와 같이 의존성 주입을 해준 상태이다.)

@Service()
export class UserService {
  constructor(
    @InjectRepository()
    private readonly userRepository: UserRepository,
  ) {}
  ...

서버를 시작할때와 동일하게 db연결을 하기전에 useContainer를 사용해주고

// sample.sepc.ts 
import { UserService } from '../services/UserService';
import { Container } from 'typedi';
import { useContainer } from 'typeorm';
...
describe('User', () => {
  it('test', async () => {
    const userService = Container.get(UserService);   // 컨테이너에서 UserService를 가져옴
    const users: User[] = await userService.getUsers();
    expect(users.length).toBe(0);
  });
});

와 같이 Container로부터 @Service로 등록한 클래스를 가져왔다.

근데 이렇게 했더니

ServiceNotFoundError Service with "MaybeConstructable" .... Register it before ... Container.set() or @Service ..

나는 분명히 @Service 데코레이터를 써줬는데 위와 같은 에러가 발생했다.
몇시간의 구글링을 통해 https://github.com/typestack/typedi/issues/173 에서 이런 글을 찾았다.

혹시나 하고 해당 버전으로 다시 설치한 후 테스트를 돌려보니


테스트가 잘 돌아간다(.....)

express환경에서 typedi와 typeorm, jest를 처음 써보기도 했고, 관련 된 자료가 많이 없는 것 같아서(내 기준)
저 단순한 테스트 하나에 8시간 이상 걸렸다.

jest.fn()으로 mocking을 하고 테스트를 진행하는 것 같은데 아직 jest를 잘 모르기도 하고
왜 안되지?하는 생각에 과몰입한 것 같기는 하다..

혹시나 나같은 상황에 있을 누군가를 위해 도움이 되었으면 좋겠다.

(질문과 논리적인 손가락질 환영합니다)

profile
💻🎸🎱🏓..

0개의 댓글