회사에서 새로운 프로젝트를 시작하는데
테스트 코드를 작성하면서 개발을 진행해보면 어떨까 싶어서
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를 잘 모르기도 하고
왜 안되지?하는 생각에 과몰입한 것 같기는 하다..
혹시나 나같은 상황에 있을 누군가를 위해 도움이 되었으면 좋겠다.