✅오늘 학습 Keyword
프로젝트 마무리 단계에 접어들었고 CI/CD를 위한 UNIT TEST CODE 작성을 시작했다.
✅오늘 겪은 문제
단위테스트에서 뭘 테스트하고자 하는지 헷갈려서 예전에 봤던 강의를 다시 찾아봤다.
단위테스트의 목적은 개별 단위가 올바르게 동작하는지를 확인하는 것이다.
1. 입출력: 함수나 메서드에 정확한 입력을 주고, 그 결과가 예상한 출력과 일치하는지 확인(즉 함수의 동작이 올바른지 확인, 예상되는 값을 입력해주어야 한다)
2. 예외처리가 필요한 경우 예외가 필요한지, 그리고 예외처리가 올바르게 동작하는지
3. 의존성: 단위 테스트에서는 주로 의존성을 가지는 외부 리소스나 모듈을 mocking하여 테스트한다
그러니까 실제 데이터베이스에 접근하여 데이터를 확인하는 것이 아니라, 데이터베이스와의 의존성을 제거하고 mocking데이터로 대체하여 함수의 '동작'만을 테스트하는 것.
✅오늘 알게된 점
nest.js 환경에서는 처음 짜보는 test code이기에 방법을 기록해둔다.
nest.js는 내장된 종속성 주입을 사용해서 쉽게 테스트 코드를 작성할 수 있도록 도와준다.
Jest를 기본 테스트 프레임 워크로 제공해주며 테스팅 패키지도 제공하기 때문에 @nestjs/testing 패키지를 사용하면 테스트에 사용되는 종속성만 선언해서 모듈을 만들어 사용한다.
import { Test } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Stores } from './stores.entity';
import { StoresRepository } from './stores.repository';
describe('StoresRepository', () => {
let repository: StoresRepository;
let storesMockRepository: Repository<Stores>;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [
StoresRepository,
{
provide: getRepositoryToken(Stores),
useClass: Repository,
},
],
}).compile();
//repository 변수에 StoresRepository클래스의 인스턴스가 할당되어 사용할 수 있게 됌,
//repository를 사용하여 StoryRepository의 메소드를 호출하고 test할 수 있음
repository = module.get<StoresRepository>(StoresRepository);
//storeMockRepository= getRepositoryToken(Stores)로 생성된 MockRepository 객체
storesMockRepository = module.get<Repository<Stores>>(
getRepositoryToken(Stores),
);
});
//사용자 위치 기반 반경 1km내의 식당 조회를 위해 전체 데이터 조회
describe('findAll', () => {
it('findAll', async () => {
const storesData: Stores[] = [
// Mock stores data
];
jest.spyOn(storesMockRepository, 'find').mockResolvedValue(storesData);
const result = await repository.findAll();
expect(result).toEqual(storesData);
expect(storesMockRepository.find).toHaveBeenCalled();
});
});
//1차 햄버거 조회
describe('searchStores', () => {
it('1차 햄버거 조회', async () => {
const keyword = 'keyword';
const sort = 'ASC';
const column = 'column';
const searchStoresData: Stores[] = [
// Mock search stores data
];
jest
.spyOn(storesMockRepository, 'find')
.mockResolvedValue(searchStoresData);
const result = await repository.searchStores(keyword, sort, column);
expect(result).toEqual(searchStoresData);
expect(storesMockRepository.find).toHaveBeenCalled();
});
});
//cycleTime 가져오기
describe('getCycleTimeByStoreId', () => {
it('가게의 cycletime 조회', async () => {
const storeId = 1;
const cycleTime = 10;
const store = new Stores();
store.storeId = storeId;
store.storeName = '';
store.description = '';
store.category = '';
store.maxWaitingCnt = 0;
store.currentWaitingCnt = 0;
store.La = 0;
store.Ma = 0;
store.address = '';
store.distance = 0;
store.oldAddress = '';
store.cycleTime = cycleTime;
store.tableForTwo = 0;
store.tableForFour = 0;
store.rating = 0;
store.coordinates = null;
store.createdAt = new Date();
store.updatedAt = new Date();
store.waitings = [];
store.reviews = [];
store.tables = null;
store.user = null;
jest.spyOn(storesMockRepository, 'findOne').mockResolvedValue(store);
const result = await repository.getCycleTimeByStoreId(storeId);
expect(result).toEqual(cycleTime);
expect(storesMockRepository.findOne).toHaveBeenCalledWith({
where: { storeId },
});
});
});
//한개 찾기
describe('findStoreById', () => {
it('한개 찾기', async () => {
const storeId = 1;
const store = new Stores();
store.storeId = storeId;
store.storeName = '';
store.description = '';
store.category = '';
store.maxWaitingCnt = 0;
store.currentWaitingCnt = 0;
store.La = 0;
store.Ma = 0;
store.address = '';
store.distance = 0;
store.oldAddress = '';
store.cycleTime = 0;
store.tableForTwo = 0;
store.tableForFour = 0;
store.rating = 0;
store.coordinates = null;
store.createdAt = new Date();
store.updatedAt = new Date();
store.waitings = [];
store.reviews = [];
store.tables = null;
store.user = null;
jest.spyOn(storesMockRepository, 'findOne').mockResolvedValue(store);
const result = await repository.findStoreById(storeId);
expect(result).toEqual(store);
expect(storesMockRepository.findOne).toHaveBeenCalledWith({
where: { storeId },
});
});
});
});
#jest.spyOn()사용법
jest.spyOn 함수는 테스트 중에 객체의 메소드를 가로채서 해당 메소드의 동작을 변경하고 모의(mock)값을 반환한다.
#test fail내역 뿐만 아니라 성공 내역도 보고싶을때
--verbose 설정
'개발 > 프로젝트-식당 웨이팅 앱 FOOD LINE' 카테고리의 다른 글
230623 실전프로젝트21 [Nest.js] 카카오맵 API에서 좌표 크롤링하기 (0) | 2023.06.23 |
---|---|
230622 실전프로젝트20 [Nest.js] Jest로 Unit test code 짜기2 (0) | 2023.06.23 |
230620 실전프로젝트18 [Nest.js] Jmeter로 부하테스트하기2 (0) | 2023.06.20 |
230619 실전프로젝트17 [Nest.js] Load balancer (0) | 2023.06.19 |
230616 실전프로젝트16 [Nest.js] Jmeter로 부하테스트하기 (0) | 2023.06.15 |