https://github.com/yhshin0/cardoc-subject
요구사항
자동차 정보 API(trimID) -> spec -> driving -> frontTire/rearTire
에 있음{폭}/{편평비}R{휠 사이즈}
과 같은 형식의 데이터일 경우만 DB에 항목별로 나누어 서로 다른 Column에 저장205/75R18
-> 타이어 폭: 205, 편평비: 75, 휠 사이즈: 18{"code":-1000,"message":"No value present"}
라는 response를 받음)AuthModule에서 JwtModule을 사용하려면 register를 통해 등록해야 하는데, 단순 register() 만으로는 ConfigModule이 읽는 .env 파일의 값을 사용할 수 없습니다.
따라서 registerAsync()를 사용하여 .env 파일의 값을 직접 넣어줘야 합니다.
이를 위해서는 AuthModule에서 ConfigModule을 import 하고, registerAsync() 에서도 import 하여 ConfigService를 사용할 수 있도록 의존성을 주입해야 합니다.
auth.module.ts
@Module({
imports: [
UsersModule,
PassportModule,
ConfigModule,
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('JWT_SECRET'),
signOptions: { expiresIn: configService.get('JWT_EXPIRATION') },
}),
}),
],
참고: https://velog.io/@algo2000/pj01-11
https://docs.nestjs.kr/techniques/configuration
private method는 mocking한 클래스에서 바로 사용하기 어렵습니다. 즉, jest.spyOn(tiresService, 'getTireInfoFromAPI')
과 같이 코드를 작성할 수 없습니다.
따라서 이를 해결하기 위해 mocking 하려는 메소드가 있는 클래스의 prototype에서 private 메소드가 실행되는지 확인해야 합니다.
tires.service.spec.ts
...
jest
.spyOn(TiresService.prototype as any, 'getTireInfoFromAPI')
.mockResolvedValue(validAPIResult);
...
참고: https://stackoverflow.com/questions/56044471/testing-private-functions-in-typescript-with-jest
typeOrm의 createQueryBuilder를 통해 DB에서 데이터를 가져오는 경우 메소드 체이닝이 되어 있기 때문에 mocking 역시 그에 맞게 코드를 작성해야 합니다.
테스트 코드에서 객체를 작성하고 체이닝 된 메소드가 호출될 때 해당 객체가 반환될 수 있도록 객체를 정의합니다.
그리고 마지막 체이닝 메소드에 원하는 결과를 반환하도록 작성한 뒤, mockImplementation() 메소드를 통해 해당 결과가 나올 수 있도록 구현합니다.
tires.service.spec.ts
const mockTiresRepository = () => ({
save: jest.fn(),
createQueryBuilder: jest.fn(),
});
...
it('유저 아이디를 통해 타이어 정보 조회에 성공한다', async () => {
...
const createQueryBuilder = {
innerJoin: () => createQueryBuilder,
where: () => createQueryBuilder,
skip: () => createQueryBuilder,
take: () => createQueryBuilder,
getManyAndCount: () => [tireList, tireList.length],
};
tiresRepository.createQueryBuilder.mockImplementation(
() => createQueryBuilder,
);
const result = await tiresService.findByUserId(userId, page, pageSize);
expect(result).toMatchObject({
totalCount: tireList.length,
data: tireList,
});
});