728x90
반응형
배경
이전 포스팅에서 Nest.js의 repository 계층 단위 테스트를 알아보았다.
https://growth-coder.tistory.com/316
[Nest.js][jest] Repository 계층 단위 테스트
jest이전에 jest 간단 사용법에 대해 포스팅 한 적이 있다.https://growth-coder.tistory.com/284 [Express] jest로 단위 테스트 하는 법이번 포스팅에서는 jest를 사용해서 단위 테스트를 진행해보려고 한다
growth-coder.tistory.com
이번 포스팅에서는 controller와 service 계층의 단위 테스트를 구현해보려고 한다.
User 엔티티와 레포지토리 계층은 이전 포스팅과 동일하다.
service 계층 단위 테스트
서비스 계층 코드는 다음과 같다.
import { Injectable } from '@nestjs/common';
import { UserRepository } from './user.repository';
import { User } from './user.entity';
@Injectable()
export class UserService {
constructor(private readonly userRepository: UserRepository) {}
async createUser(
username: string,
password: string,
): Promise<User> {
return this.userRepository.createUser(username, password);
}
async findByUserName(username: string): Promise<User | null> {
return this.userRepository.findByUserName(username);
}
}
현재 UserService는 UserRepository에 의존을 하고 있기 때문에 UserRepository의 메소드들을 모킹한다.
describe('UserService', () => {
let userService: UserService;
const newUser = {
id: 1,
username: 'test',
password: 'test',
};
const user = new User();
Object.assign(user, newUser);
const userRepository = {
createUser: jest.fn().mockResolvedValue(user),
findByUserName: jest.fn((username) =>
username === 'test' ? Promise.resolve(user) : Promise.resolve(null),
),
};
};
createUser는 미리 만들어둔 User를 Promise로 반환하고 findByUserName은 username이 test일 때만 User를 Promise로 반환한다.
import { Test, TestingModule } from '@nestjs/testing';
import { UserService } from './user.service';
import { UserRepository } from './user.repository';
import { User } from './user.entity';
describe('UserService', () => {
let userService: UserService;
const newUser = {
id: 1,
username: 'test',
password: 'test',
};
const user = new User();
Object.assign(user, newUser);
const userRepository = {
createUser: jest.fn().mockResolvedValue(user),
findByUserName: jest.fn((username) =>
username === 'test' ? Promise.resolve(user) : Promise.resolve(null),
),
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserService,
{
provide: UserRepository,
useValue: userRepository,
},
],
}).compile();
userService = module.get<UserService>(UserService);
});
it('should be defined', () => {
expect(userService).toBeDefined();
});
it('createUser', async () => {
const createdUser = await userService.createUser('test', 'test');
expect(createdUser).toBe(user);
});
it('findByUserName', async () => {
const findUser = await userService.findByUserName('test');
expect(findUser).toBe(user);
});
});
controller 계층 단위 테스트
컨트롤러 계층 코드는 다음과 같다.
import { Controller, Post, Get, Body, Param } from '@nestjs/common';
import { UserService } from './user.service';
import { User } from './user.entity';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Post()
async createUser(
@Body('username') username: string,
@Body('password') password: string,
): Promise<User> {
return this.userService.createUser(username, password);
}
@Get(':username')
async findByUserName(@Param('username') username: string): Promise<User | null> {
return this.userService.findByUserName(username);
}
}
역시 UserService를 모킹한다.
describe('UserController', () => {
let userController: UserController;
let userService: UserService;
const mockUser: User = {
id: 1,
username: 'test',
password: 'test',
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
providers: [
{
provide: UserService,
useValue: {
createUser: jest.fn().mockResolvedValue(mockUser),
findByUserName: jest.fn().mockResolvedValue(mockUser),
},
},
],
}).compile();
userController = module.get<UserController>(UserController);
userService = module.get<UserService>(UserService);
});
});
이제 테스트 코드를 작성하면 된다.
import { Test, TestingModule } from '@nestjs/testing';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { User } from './user.entity';
describe('UserController', () => {
let userController: UserController;
let userService: UserService;
const mockUser: User = {
id: 1,
username: 'test',
password: 'test',
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
providers: [
{
provide: UserService,
useValue: {
createUser: jest.fn().mockResolvedValue(mockUser),
findByUserName: jest.fn().mockResolvedValue(mockUser),
},
},
],
}).compile();
userController = module.get<UserController>(UserController);
userService = module.get<UserService>(UserService);
});
describe('createUser', () => {
it('should create a new user', async () => {
const username = 'test';
const password = 'test';
const result = await userController.createUser(username, password);
expect(result).toEqual(mockUser);
expect(userService.createUser).toHaveBeenCalledWith(username, password);
});
});
describe('findByUserName', () => {
it('should return a user by username', async () => {
const username = 'test';
const result = await userController.findByUserName(username);
expect(result).toEqual(mockUser);
expect(userService.findByUserName).toHaveBeenCalledWith(username);
});
it('createUser not found', async () => {
jest.spyOn(userService, 'findByUserName').mockResolvedValueOnce(null);
const result = await userController.findByUserName('test');
expect(result).toBeNull();
expect(userService.findByUserName).toHaveBeenCalledWith('test');
});
});
});
728x90
반응형
댓글