식품의 개수는 냉장고에서 꺼낸 개수만큼 줄어든다.
새로운 기능추가 요건은 식품의 개수를 줄이는 것이다.
FoodTests 클래스에 개수를 줄이는 테스트 메서드를 추가한다. 그리고 cola 인스턴스를 생성한다.
@Test public void decreaseQuantity() { Food cola = new Food("코카콜라 500mL", 2, "2018-10-30"); }
Food 객체의 수량을 줄이는 메서드를 다음과 같이 만들고 확인해본다.
@Test public void decreaseQuantity() { Food cola = new Food("코카콜라 500mL", 2, "2018-10-30"); cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(1)); }
decreaseQuantity 메서드를 만든 기억이 없다. Quick Fix로 재빨리 구현하고, 테스트를 실행한다.
public void decreaseQuantity(int quantity) { // TODO Auto-generated method stub }
decreaseQuantity 메서드를 구현했지만, 신호등은 빨간불이다. 1편에서 말한것처럼 무슨 수를 써서라도 신호등 불을 초록으로 만들어야 한다.
public void decreaseQuantity(int quantity) { this.quantity = 1; }
이제 신호등 불은 초록불이 되었지만, 이건 아니라고 당연히 생각한다. 테스트를 추가하면 바로 확인할 수 있다.
@Test public void decreaseQuantity() { Food cola = new Food("코카콜라 500mL", 2, "2018-10-30"); cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(1)); cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(0)); }
콜라를 꺼내먹고, 또 꺼내먹으면 냉장고에 콜라가 없다고 예상되지만 결과는 1이다. 정상적으로 코드를 구현할 때가 왔다.
public void decreaseQuantity(int quantity) { this.quantity -= quantity; }
테스트는 성공적으로 실행된다. 그러면 한번 더 꺼내먹으면 어떻게 되는걸까? 없는걸 꺼낼 수 없으니 에러를 발생하면 된다.
public void decreaseQuantity(int quantity) { if(this.quantity - quantity < 0) { throw new IllegalArgumentException("current(" + this.quantity + "), quantity(" + quantity + ")"); } this.quantity -= quantity; }
현재 보유 개수에서 파라미터로 전달된 개수를 뺀 것이 0 미만일 경우 IllegalArgumentException을 생성해서 예외를 던진다. FoodTests 에서는 cola 를 또 꺼내 먹도록 코드를 작성하고, 예외가 발생할 것이라고 예상되므로 @Test 애노테이션에 예외클래스를 기대된다고 명시하면 테스트는 성공한다.
@Test(expected=IllegalArgumentException.class) public void decreaseQuantity() { Food cola = new Food("코카콜라 500mL", 2, "2018-10-30"); cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(1)); cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(0)); cola.decreaseQuantity(2); }
그런데, Food 객체의 decreaseQuantity 메서드는 파라미터 int quantity 의 값을 양의 값이라고 가정하고 있다. 이것을 확인해본다. 새로운 Test메서드를 하나 추가하고 음의 값을 넣어서 확인해본다.
@Test public void decreaseQuantityByNegativeQuantity() { Food cola = new Food("코카콜라 500mL", 2, "2018-10-30"); cola.decreaseQuantity(-2); assertThat(cola.getQuantity(), equalTo(0)); }
콜라를 -2개 꺼내먹었으니 콜라가 남지 않았을 거라고 예상했지만, 신호등은 빨간불이 들어왔고, 4개가 리턴되었다. 이 부분도 예외로 처리할 수 있다.
public void decreaseQuantity(int quantity) { if(quantity < 0 || this.quantity - quantity < 0) { throw new IllegalArgumentException("current(" + this.quantity + "), quantity(" + quantity + ")"); } this.quantity -= quantity; }
테스트 메서드에 애노테이션에 예외를 등록하고 실행해보면 성공한다.
@Test(expected=IllegalArgumentException.class) public void decreaseQuantityByNegativeQuantity() { Food cola = new Food("코카콜라 500mL", 2, "2018-10-30"); cola.decreaseQuantity(-2); assertThat(cola.getQuantity(), equalTo(0)); }
테스트 코드에 cola 인스턴스가 반복적으로 나타난다. 이 부분을 junit의 @Before 애노테이션 선언한 메서드에 미리 Food 객체를 생성해두면 테스트가 실행될 때 모두 독립적으로 사용 할 수 있다.
cola 인스턴스를 만들면서 milk도 만들어 두고 각 테스트 메서드에 존재하는 객체 생성코드들을 모두 삭제하고 다시 실행해서 확인한다.
전체 FoodTests 코드는 다음과 같다.
package com.poseidon.fridge; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import org.junit.Before; import org.junit.Test; public class FoodTests { private Food milk; private Food cola; @Before public void setUp() { milk = new Food("파스퇴르 우유 1.8L", 1, "2018-09-28"); cola = new Food("코카콜라 500mL", 2, "2018-10-30"); } @Test public void createFood() { String name = milk.getName(); int quantity = milk.getQuantity(); String expiryDate = milk.getExpiryDate(); assertThat(name, equalTo("파스퇴르 우유 1.8L")); assertThat(quantity, equalTo(1)); assertThat(expiryDate, equalTo("2018-09-28")); assertThat(cola.getName(), equalTo("코카콜라 500mL")); assertThat(cola.getQuantity(), equalTo(2)); assertThat(cola.getExpiryDate(), equalTo("2018-10-30")); } @Test(expected=IllegalArgumentException.class) public void decreaseQuantity() { cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(1)); cola.decreaseQuantity(1); assertThat(cola.getQuantity(), equalTo(0)); cola.decreaseQuantity(2); } @Test(expected=IllegalArgumentException.class) public void decreaseQuantityByNegativeQuantity() { cola.decreaseQuantity(-2); assertThat(cola.getQuantity(), equalTo(0)); } }
이전글: 냉장고 가계부 프로젝트 1
다음글: 냉장고 가계부 프로젝트 3