NestJS의 Typeorm repository가 inject된 service 테스트하기

NestJS에서_Typeorm_repository_injected_service_테스트하기.jpg

프로젝트에서 DB를 사용하기 위해 TypeOrmModule을 사용하고 있다.

테스트대상 서비스가 TypeOrmModule의 repository를 의존성으로 갖고 있는 경우, 이 서비스를 어떻게 테스트해야 할까?

테스트코드에서 실제 데이터베이스에 연결하거나 테스트용 데이터베이스를 굳이 연결하고 싶지 않다면, 의존서비스의 메소드가 말 그대로 존재만 하고 아무 기능도 하지 않는 mock로 만들면 된다.

최근 Service 클래스나 커스텀 repository에서 Typeorm의 repository를 inject한 경우, 테스트코드를 작성하게 되어 요령을 공유한다.

describe('CustomRepository', () => {
    let customRepository: CustomRepository;
    // Repository의 전체 메소드를 구현하지 않도록 Pick으로 선택한다. 여기서는 save만를 구현한다.
    const repositoryMock: jest.Mocked<Pick<Repository<EntityName>, 'save'>> =
        {
            save: jest.fn(),
        };
    // save의 동작은 jest.fn 이 반환한 jest.Mock의 mockImplementation 을 통해 구현할 수 있다.
    repositoryMock.save.mockImplementation(
        // mockImplementation 으로 구현할 때 기존 메소드의 type을 지켜야 한다. 여기서는 cast 하였다.
        async (entity: DeepPartial<EntityName>) => {
            // something todo
            return entity as DeepPartial<EntityName> & EntityName;
        },
    );

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [
                CustomRepository,
                // module 내에 dependency가 없는 문제 해결
                {
                    provide: getRepositoryToken(EntityName),
                    useValue: RepositoryMock,
                },
            ],
        }).compile();
        customRepository = module.get<CustomRepository>(CustomRepository);
    });

    it('should be defined', async () => {
        await customRepository.save({
            key: 'value'
        });
    });
});