[Jest] 4. SuperMarket 테스트 코드 작성 및 에러 처리
이전 게시글 3. Matchers & SuperMarket 테스트 코드 작성 준비에서 확인한 SuperMarket Class의 테스트 코드를 작성해봅시다. 그리고 시작하기 전 미리 말씀드리면 package.json에 script를 아래와 같이 수정해주세요.
"scripts": {
"test": "jest --watch --verbose"
}
SuperMarket 테스트 코드 작성하기
이전 게시글에서 확인한 SuperMarket Class의 테스트 코드를 한번 작성해보셨나요? 안해보셨다면 지금이라도 해보시고 확인하시는 것을 추천드립니다. 우선 저 같은 경우는 아래와 같이 작성하였습니다.
const SuperMarket = require("../superMarket.js");
describe("SuperMarket", () => {
let superMarket = null;
beforeEach(() => {
superMarket = new SuperMarket();
});
describe("초기 금액 확인", () => {
it("초기 잔고는 5000원입니다", () => {
expect(superMarket.balance).toBe(5000);
});
it("snack 금액은 2000원입니다", () => {
expect(superMarket.snack).toBe(2000);
});
it("chocolate 금액은 1000원입니다", () => {
expect(superMarket.chocolate).toBe(1000);
});
it("icecream 금액은 3000원입니다", () => {
expect(superMarket.icecream).toBe(3000);
});
it("gum 금액은 500원입니다", () => {
expect(superMarket.gum).toBe(500);
});
});
describe("구매 확인", () => {
it("2000원 지불 / snack 1개 구매 / 거스름돈 : 0원 / 잔고 : 5000원", () => {
expect(superMarket.buy("snack", 1, 2000)).toBe(0);
expect(superMarket.getItemPrice("balance")).toBe(5000);
});
it("2000원 지불 / chocolate 2개 구매 / 거스름돈 : 0원 / 잔고 : 5000원", () => {
expect(superMarket.buy("chocolate", 2, 2000)).toBe(0);
expect(superMarket.getItemPrice("balance")).toBe(5000);
});
it("3500원 지불 / icecream 1개 구매 / 거스름돈 : 500원 / 잔고 : 5500원", () => {
expect(superMarket.buy("icecream", 1, 3500)).toBe(500);
expect(superMarket.getItemPrice("balance")).toBe(5500);
});
it("1400원 지불 / gum 3개 구매 / 거스름돈 : -1원 / 잔고 : 5000원", () => {
expect(superMarket.buy("gum", 3, 1400)).toBe(-1);
expect(superMarket.getItemPrice("balance")).toBe(5000);
});
});
});
이해가 되실까요? 제가 작성한 코드에 대해 약간의 설명을 추가해보겠습니다.
- describe
describe는 비슷한 맥락(?)끼리 묶어주는 역할을 합니다. 저는 SuperMarket을 기준으로 describe를 하였습니다. 그리고 추가로 그 안에서 초기 금액 확인, 구매 확인으로 또 나누었습니다. 이렇게 나누게 되면 이후 테스트 코드 실행 시 결과창이 깔끔해 진 것을 볼 수 있습니다. 다시 말하면 문서화 하기 좋습니다. 나중에 타 개발자가 내가 작성한 테스트 코드만 보고도 아! 해당 코드가 무엇을 하는 것이구나 라는 것을 알 수 있게 됩니다. 진짜 그런 지 아래 결과를 확인해봅시다.
테스트 결과가 한눈에 보아도 문서화가 되어 있죠? 이렇게 문서화 작업을 따라하지 않아도 되도록 테스트 코드를 잘 작성해주는 것이 중요합니다.
- beforeEach
저번 게시글에서 beforeEach에 대해 잠깐 언급하였는데요. 테스트 작성 시 필요해보여서 미리 언급하였습니다. beforeEach는 각각의 테스트가 실행되기 전 실행하는 함수입니다. 모든 테스트는 독립적이어야 합니다. 다시 말하면 A 테스트가 B 테스트에 영향을 끼치면 안된다는 것이죠. 따라서 혹시 모를 문제를 예방하기 위해 각각의 테스트 전 SuperMarket의 객체를 생성해준 것입니다.
SuperMarket Class 및 테스트 코드 개선하기
위 SuperMarket Class와 테스트 코드를 개선해봅시다. 1가지만 개선해보려고 하는데요. buy 함수에서 구매하지 못 하는 경우 -1을 return 해줍니다. 그러나 사실 이 경우 error가 발생하는 것이 맞겠죠? 아래처럼 buy 함수를 수정해줍시다.
buy(item, count, paidAmount) {
const totalPrice = this.getItemPrice(item) * count;
if (paidAmount >= totalPrice) {
this.balance += paidAmount - totalPrice;
return paidAmount - totalPrice;
} else {
return -1;
}
}
buy(item, count, paidAmount) {
const totalPrice = this.getItemPrice(item) * count;
if (paidAmount >= totalPrice) {
this.balance += paidAmount - totalPrice;
return paidAmount - totalPrice;
} else {
throw new Error("금액이 부족합니다.");
}
}
그럼 테스트 결과가 아래처럼 실패로 표시됩니다.
너무나 당연한 결과입니다. 우리가 superMarket의 buy 함수를 수정했으니 test code도 거기에 맞게 수정을 해주어야겠죠? test code를 아래와 같이 수정해줍니다.
it("1400원 지불 / gum 3개 구매 / 거스름돈 : -1원 / 잔고 : 5000원", () => {
expect(superMarket.buy("gum", 3, 1400)).toBe(-1);
expect(superMarket.getItemPrice("balance")).toBe(5000);
});
it("1400원 지불 / gum 3개 구매 / 에러 처리 / 잔고 : 5000원", () => {
expect(() => superMarket.buy("gum", 3, 1400)).toThrow(
"금액이 부족합니다."
);
expect(superMarket.getItemPrice("balance")).toBe(5000);
});
그럼 모든 test가 정상적으로 통과하게 됩니다. 아래 결과를 확인해봅시다.
그럼 어떻게 에러가 발상하는 것을 처리하는 test code를 작성할 수 있을까요? 위에서 수정 후 코드를 보았듯이 에러 test code를 작성하는 방법은 아래와 같습니다.
expect(() => test_코드_함수()).toThrow(에러_메시지);
위와 같이 에러 테스트 코드를 작성하시면 됩니다.
참고자료
마지막
해당 내용은 틀릴 수도 있습니다. 틀린 내용이 있으면 조언 부탁드립니다.
'기타 (+ Legacy) > Legacy' 카테고리의 다른 글
[테스트 코드 - Jest] mock 함수 (0) | 2022.03.09 |
---|---|
[테스트 코드 - Jest] 비동기 테스트 코드 작성 (0) | 2022.03.08 |
[테스트 코드 - Jest] Matchers & SuperMarket 테스트 코드 작성 준비 (0) | 2022.03.04 |
[테스트 코드 - Jest] Test Code 작성 및 Jest 설정 추가 (0) | 2022.03.03 |
[테스트 코드 - Jest] Jest 설치 및 셋팅 (0) | 2022.03.02 |