productModel.save
메소드 검증 추가it("should call ProductModel", async () => {
// createProduct() 함수가 실행 될 때
await createProduct(req, res, next);
// 내부에서 new Product()가 실행 되는지
// 여기서 단위테스트 이기 때문에 실제 Model에 영향을 받으면 안되기 떄문에 Mock 함수 사용
// toBeCalledWith 함수를 통해 어떤 인자를 받았는지도 함께 검증
expect(Product).toBeCalledWith(newProduct);
// productModel.save 메소드 검증
const productModel = new Product(newProduct);
expect(productModel.save).toBeCalled();
});
it("should return 201 response code", async () => {
await createProduct(req, res, next);
expect(res.statusCode).toBe(201);
// res.send() Test
expect(res._isEndCalled()).toBeTruthy();
});
it("should return json body in response", async () => {
const productModel = new Product(newProduct);
// mock 함수에 리턴값을 req.body 값으로 설정
(productModel.save as jest.Mock).mockReturnValue(newProduct);
await createProduct(req, res, next);
expect(res._getJSONData()).toStrictEqual(newProduct);
});
에러 발생시키는 방법
required: true
로 설정한 경우 해당 프로퍼티를 포함해서 디비에 저장해야 합니다.몽고 디비에서 처리하는 부분은 문제가 없다는 것을 가정하고 단위 테스트를 진행하기 때문에 몽고 디비에서 발생시키는 에러 부분은 Mock 함수를 통해 처리합니다.
단위 테스트 작성
next=null
값을 jest.fn()
을 통해 mock 함수로 만들어 줍니다.import { createProduct } from "../../src/controllers/products";
import { Product } from "../../src/models/product";
import httpMocks from "node-mocks-http";
import newProduct from "../data/new-product.json";
// Model mock 함수
// 어떤 것에 의해서 호출되었는지 / 어떤 것과 함께 호출되는지 알 수 있습니다. ( 스파이 역할 )
jest.mock("../../src/models/product");
let req: any, res: any, next: any;
// beforeEach() 때문에 모든 테스트 케이스에 똑같이 적용
beforeEach(() => {
// express controller가 받을 수 있는 인자 생성
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
});
it("should handle errors", async () => {
// description 프로퍼티가 없을 때 발생하는 에러 메시지 정의
const errorMessage = { message: "description property missing" };
// 비동기 처리에서 에러 프로미스 정의
const rejectedPromise = Promise.reject(errorMessage);
const productModel = new Product(newProduct);
// mock 함수의 리턴 값을 정의 => rejectedPromise 반환
(productModel.save as jest.Mock).mockReturnValue(rejectedPromise);
// product create 함수 호출
await createProduct(req, res, next);
// 테스트: productController.createProduct() 함수에서 에러가 발생해서 next() 함수를 호출
// next 함수를 호출할 때 errorMessage가 넘어가는지 확인하는 테스트
expect(next).toBeCalledWith(errorMessage);
});