Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- react
- 정렬
- TypeScript
- 게임
- JavaScript
- mongoose
- AWS
- jest
- Bull
- nodejs
- dfs
- OCR
- 공룡게임
- class
- cookie
- 자료구조
- Python
- Sequelize
- nestjs
- Dinosaur
- MySQL
- MongoDB
- GIT
- typeORM
- flask
- Nest.js
- Express
- game
- Queue
Archives
- Today
- Total
포시코딩
[Jest] 오토 모킹 vs 수동 모킹 본문
728x90
오토 모킹
import { Test, TestingModule } from '@nestjs/testing';
import { ModuleMocker, MockFunctionMetadata } from 'jest-mock';
const moduleMocker = new ModuleMocker(global);
// ModuleMocker는 getMetadata 메서드를 사용해 모듈의 메타데이터를 생성하고
// generateFromMetadata 메서드를 사용해 메타데이터를 바탕으로 모듈을 모킹한다.
// 즉, 오토 모킹의 핵심
describe('ChatService', () => {
let service: ChatService; // ChatService 인스턴스
let mockChatRepository: jest.Mocked<ChatRepository>; // ChatRepository의 모킹된 버전
beforeEach(async () => { // 각각의 테스트 코드 전에 실행
jest.clearAllMocks(); // 이전에 모킹된 모든 함수 초기화
const module: TestingModule = await Test.createTestingModule({
providers: [ChatService], // ChatService를 포함한 providers를 생성
}).useMocker((token) => { // providers를 모킹(Mocking). token은
// useMocker는 콜백 함수를 인자로 받는데 (token), 이 콜백 함수는 provider의 종류에 따라 다른 타입을 가지며, 주로 함수 타입을 가진다.
if (typeof token === 'function') { // provider가 함수일 경우
const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>; // 함수의 메타데이터(MockFunctionMetadata)를 가져온다.
const Mock = moduleMocker.generateFromMetadata(mockMetadata); // 메타데이터를 바탕으로 모킹된 함수 생성
return new Mock(); // 인스턴스를 생성하고 반환
// 이렇게 모킹된 함수는 useMocker() 함수가 호출된 createTestingModule() 함수 안에 있는
// providers 중에서 해당 함수와 일치하는 타입의 provider를 대체(Mocking)한다.
}
}).compile(); // 컴파일된 TestingModule을 반환
service = module.get(ChatService); // service 변수에 위에서 선언된 ChatService 인스턴스 할당
mockChatRepository = module.get(ChatRepository); // mockChatRepository에 ChatRepository의 모킹된 버전 할당
// 이후부터 service의 메서드를 호출해 ChatService의 메서드를 호출 할 수 있고
// mockChatRepository 변수를 사용해 ChatRepository의 모킹된(Mocked) 메서드를 호출하며 테스트를 진행할 수 있다.
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('getChatRooms Method', () => {
const userId = 1;
it('success', async () => {
const mockReturnValue = [new Meetup()];
mockChatRepository.getChatRooms.mockResolvedValue(mockReturnValue);
// mockChatRepository의 getChatRooms 메서드에 대해 리턴타입이 Promise인 것을 감안해 mockResolvedValue를 사용하는 부분
// mockResolvedValue 함수는 특정 함수가 비동기 함수인 경우, 해당 함수가 호출되면 반환되는 값을 프로미스 형태로 반환하도록 설정한다.
// 이를 통해 테스트에서 특정 비동기 함수의 반환 값을 쉽게 모킹(Mocking) 할 수 있다.
const result = await service.getChatRooms(userId);
expect(result).toBe(mockReturnValue);
expect(mockChatRepository.getChatRooms).toHaveBeenCalled();
expect(mockChatRepository.getChatRooms).toHaveBeenCalledWith(userId);
expect(result).toBeInstanceOf(Array);
});
});
}
수동 모킹
import { Test, TestingModule } from '@nestjs/testing';
describe('ChatService', () => {
let service: ChatService;
let mockChatRepository: ChatRepository;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ChatService,
{
provide: ChatRepository,
useValue: {
getChatRooms: jest.fn(),
exitChatRoom: jest.fn(),
insert: jest.fn(),
find: jest.fn(),
}
}
],
}).compile();
service = module.get(ChatService);
mockChatRepository = module.get(ChatRepository);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('getChatRooms Method', () => {
const userId = 1;
it('success', async () => {
const mockReturnValue = [new Meetup()];
jest.spyOn(mockChatRepository, 'getChatRooms').mockResolvedValue(mockReturnValue);
const result = await service.getChatRooms(userId);
expect(result).toBe(mockReturnValue);
expect(mockChatRepository.getChatRooms).toHaveBeenCalled();
expect(mockChatRepository.getChatRooms).toHaveBeenCalledWith(userId);
expect(result).toBeInstanceOf(Array);
});
});
});
차이점
- 오토 모킹할 땐 provide된 ChatRepository의 각 메서드들에 대해 하나하나 세팅할 필요가 없었던 반면
수동에선 provide와 useValue를 통해 chatRepository에 대한 가짜 객체를 만든다. - 수동에선 chatRepository의 모든 함수를 jest.fn()을 통해 모킹한다.
mockChatRepository.getChatRooms.mockResolvedValue(mockReturnValue);
오토 모킹에선 위의 방법으로 반환 값을 모킹한 반면
jest.spyOn(mockChatRepository, 'getChatRooms').mockResolvedValue(mockReturnValue);
수동 모킹에선 jest의 spyOn 함수를 통해 mockChatRepository의 getChatRooms 메서드에 대해 반환 값을 모킹하고 있다.
728x90
'Test Case' 카테고리의 다른 글
[Jest] mockImplementation, mockResolvedValue (0) | 2023.07.17 |
---|---|
테스트 코드(Test Code) - supertest (0) | 2023.01.08 |
테스트 코드(Test Code) - Jest (0) | 2022.12.31 |
assert문이란? (0) | 2022.11.19 |
코드 커버리지(Code Coverage)란? (0) | 2022.11.19 |