혼자 고민해보기_ 개발/TIL (Today I Learned)
20231113(월)_ Jest 테스트코드_ Nest can't resolve dependencies of the UserGuard (?, ConfigService). Please make sure that the argument JwtService at index [0] is available in the RootTestModule context.
nuri-story
2023. 11. 13. 21:31
금일 달성 항목
1) user.controller.spec.ts testcode 진행
문제 해결 과정 1 - Nest can't resolve dependencies of the UserGuard (?, ConfigService). Please make sure that the argument JwtService at index [0] is available in the RootTestModule context.
[문제]
user.controller.spec.ts testcode 진행 중에 자꾸만 아래와 같은 오류가 떠서 해결이 되지 않았다. JwtService가 User.controller.ts에 존재하지 않는데 자꾸만 찾았다 ㅠㅠ
FAIL src/apis/user/test/user.controller.spec.ts
UserController
getUser
getUser가 호출될때
✕ userService를 호출해야 한다 (9 ms)
● UserController › getUser › getUser가 호출될때 › userService를 호출해야 한다
Nest can't resolve dependencies of the UserGuard (?, ConfigService). Please make sure that the argument JwtService at index [0] is available in the RootTestModule context.
Potential solutions:
- Is RootTestModule a valid NestJS module?
- If JwtService is a provider, is it part of the current RootTestModule?
- If JwtService is exported from a separate @Module, is that module imported within RootTestModule?
@Module({
imports: [ /* the Module containing JwtService */ ]
})
17 |
18 | beforeEach(async () => {
> 19 | const moduleRef = await Test.createTestingModule({
| ^
20 | controllers: [UserController],
21 | providers: [
22 | UserService,
[시도 및 해결]
확인해보니 @UseGuards(UserGuard) 흘러들어오는 Jwtservice 였다.. 내가 user와 auth부분을 담당하지 않았어서 흐름을 잘 몰라서 그랬었다. 저 부분을 주석처리하니 잘 해결되었다.
PASS src/apis/user/test/user.controller.spec.ts
UserController
getUser
getUser가 호출될때
✓ userService를 호출해야 한다 (12 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.069 s
문제 원인
1. Usergards 가 문제인 것 같은데 추적이 필요
2. MailService가 usercontroller에 있는 것도 문제
user.controller.ts
// 유저정보 상세조회
// @UseGuards(UserGuard)
@Get('/user-page')
@ApiOperation({
summary: '(유저가드 적용) 유저정보 상세조회 API',
description: '(유저가드 적용) 유저정보 상세조회',
})
@ApiCreatedResponse({
description: '(유저가드 적용) 유저정보 상세조회',
type: User,
})
findOneUser(@Request() req) {
// if (id) {
// console.log('findOne = ', id);
// return this.userService.findOne(id);
// }
// AuthGuard로 받은 req안에 user에 접근하면 현재 로그인한 유저(회사)의 정보에 접근할 수 있습니다.
return this.userService.getUserById(req.user.id);
}
// 유저정보 조회
@Get('/user/:id')
@ApiOperation({
summary: '유저정보 조회 API',
description: '유저 정보조회',
})
@ApiCreatedResponse({ description: '유저 정보조회', type: User })
findUser(@Param('id') id: string) {
return this.userService.getUserById(id);
}
user.controller.spec.ts
import { Test } from '@nestjs/testing';
import { User } from 'src/apis/domain/user.entity';
import { UserController } from '../user.controller';
import { UserService } from '../user.service';
import { userStub } from './stubs/user.stub';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { MailService } from 'src/apis/mail/mail.service';
import { ConfigService } from '@nestjs/config';
import { getRepositoryToken } from '@nestjs/typeorm';
import { UserGuard } from 'src/apis/auth/jwt/jwt.user.guard';
jest.mock('../user.service');
describe('UserController', () => {
let userController: UserController;
let userService: UserService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
controllers: [UserController],
providers: [
UserService,
{
provide: getRepositoryToken(User),
useValue: userStub(),
},
{
provide: UserGuard,
useValue: jest.fn().mockImplementation(() => true),
},
ConfigService,
],
})
.overrideProvider(UserService)
.useValue(userService)
.compile();
userController = moduleRef.get<UserController>(UserController);
userService = moduleRef.get<UserService>(UserService);
jest.clearAllMocks();
});
describe('getUser', () => {
describe('getUser가 호출될때', () => {
let user: User;
beforeEach(async () => {
user = await userController.findUser(userStub().id);
});
test('userService를 호출해야 한다', () => {
expect(userService.getUserById).toHaveBeenCalledWith(userStub().id);
expect(user).toEqual(userStub());
});
});
});
});
[참고]
https://www.youtube.com/watch?v=43iQzPJvZDw