[ Jest ] 단위(unit)테스트와 통합테스트
in BackEnd
서비스 규모가 크면 클수록 테스트 코드를 짜는건 필수다.
경험상 테스트코드의 작성이 얼마나 중요할지 수업을 들으면서 사실 바로 이해는 갔지만 한번도 써본적이 없어서 어떻게 하는건지 사실은 아직도 감이 그렇게 오지는 않는다.
특히 express와 NestJS의 방식이 좀 많이 다른것 같아서 그것도 너무 헷갈린다;;;;
뭘 어떻게 해야하는거야…..
나중에는 TDD로 어플리케이션을 꼭 만들어보고싶다.
테스트 코드를 짰을때 ‘이건 짜고 치는 고스톱아니야…?’ 혹은 ‘배보다 배꼽이 더 큰거 아니야…?’ 라는 생각이 들떄도 있었지만
그래도 여러 영상들을 찾아보면 있어야하는 필수템이라는 생각은 든다.
단위(Unit) 테스트
단위 테스트는 소스 코드의 개별 단위를 테스트하여 준비가 되었는지 확인하는 테스트 방법.
메서드를 테스트하는 메서드
단위테스트의 조건
- 독립적이어야 하며, 다른 테스트에 의존하지 않아야함
- 격리되어야 한다. Ajax, Axios 등 테스트 대상이 의존하는 것을 다른 것으로 대체해야 함
왜 사용하는가?
- 서비스가 클수록 로컬에서 내가 짠 코드를 실행시키기 어렵기 떄문이다. 실제로 디비와 연결된 데이터를 처리하다가 잘못된 데이터가 생성된다거나 데이터를 오염시킬 가능성도 크고, 그 모킹데이터를 찾아 매번 삭제를 하거나 트랜잭션이나 롤백을 하기가 어렵다.
- 종속성이 있는 다른 클래스들에서 버그가 나는 것을 방지
Jest
Facebook이 만든 테스팅 프레임워크. 단위 테스트를 위해 사용한다
test나 spec이 들어간 파일이름을 찾아 실행한다.
추천하는 VSC익스텐션 : Jest Runner
테스트 파일 내에서도 단위 하나하나 개별적으로 실행할 수 있음
jest.fn()
Mock함수를 생성하는 함수. 해당 코드가 의존하는 부분을 가짜로 대체해줌
productModel.create = jest.fn();
let req, res, next;
beforeEach(() => {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
})
describe("Product Controller Create", () => {
beforeEach(() => {
req.body = newProduct;
})
it("should call ProductModel.create", async () => {
await productController.createProduct(req, res, next);
expect(productModel.create).toBeCalledWith(newProduct);
})
})
통합(Integration) 테스트
단위 테스트를 먼저 수행하고 문제가 없다면, 이 모듈들을 모아 한꺼번에 테스트 수행
왜 사용하는가?
- 모듈들의 상호 작용이 잘 이루어지는지 검증하기 위해서
- 통합하는 과정에서 발생할 수 있는 오류를 찾기 위해서
Supertest
Nodes http서버를 테스트하기 위해 만들어진 모듈. 통합 테스트를 쉽게 구현할 수 있음
it("POST /api/products", async () => {
const response = await request(app)
.post("/api/products")
.send(newProduct);
expect(response.statusCode).toBe(201)
expect(response.body.name).toBe(newProduct.name)
expect(response.body.description).toBe(newProduct.description)
})