自動販売機をTDDで実装する
例題
> TDDBC大阪
購入できるかどうかを調べるために、isPurchacable() メソッドを追加する。
@Test public void testIsPurchacable() { VendingMachine vm = new VendingMachine(); boolean b = vm.isPurchacable(); assertThat(b, is(false)); }
Eclipseでメソッドを生成するとテストをパスするようになる。
public boolean isPurchacable() { return false; }
500円を投入すると購入可能になるテストを追加する。
@Test public void testIsPurchacable() { VendingMachine vm = new VendingMachine(); boolean b = vm.isPurchacable(); assertThat(b, is(false)); vm.throwInto(500); b = vm.isPurchacable(); assertThat(b, is(true)); }
自動販売機の購入の動作を実装する
お金を入れてボタンを押すとジュースとおつりが出てくる。
それっぽいテストを書いてみる。
出てくるもの(ジュースとおつり)をまとめて Output クラスとしておく。
VendingMachineTest.java
@Test public void testPurchace() { VendingMachine vm = new VendingMachine(); vm.throwInto(100); vm.throwInto(10); vm.throwInto(10); Output o = vm.purchace(); assertThat(j, is(1)); assertThat(change, is(0)); }
Output.java
public class Output { private int juiceCount; private int change; public Output(int juiceCount, int change) { this.juiceCount = juiceCount; this.change = change; } public int getJuiceCount() { return juiceCount; } public int getChange() { return change; } }
ここまでのコードは以下のとおり。
VendingMachineTest.java
import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import org.junit.Test; public class VendingMachineTest { @Test public void testThrowInto() { VendingMachine vm = new VendingMachine(); int change = vm.throwInto(10); assertThat(change, is(0)); int total = vm.getTotal(); assertThat(total, is(10)); change = vm.throwInto(50); assertThat(change, is(0)); total = vm.getTotal(); assertThat(total, is(60)); } @Test public void testThrowIntoNotAccept() { VendingMachine vm = new VendingMachine(); int change = vm.throwInto(1); assertThat(change, is(1)); int total = vm.getTotal(); assertThat(total, is(0)); change = vm.throwInto(5); assertThat(change, is(5)); change = vm.throwInto(2000); assertThat(change, is(2000)); change = vm.throwInto(5000); assertThat(change, is(5000)); change = vm.throwInto(10000); assertThat(change, is(10000)); } @Test public void testThrowIntoRefund() { VendingMachine vm = new VendingMachine(); int change = vm.throwInto(10); assertThat(change, is(0)); int total = vm.getTotal(); assertThat(total, is(10)); int refund = vm.refund(); assertThat(refund, is(10)); total = vm.getTotal(); assertThat(total, is(0)); change = vm.throwInto(100); assertThat(change, is(0)); total = vm.getTotal(); assertThat(total, is(100)); change = vm.throwInto(500); assertThat(change, is(0)); total = vm.getTotal(); assertThat(total, is(600)); refund = vm.refund(); assertThat(refund, is(600)); } @Test public void testGetJuice() { VendingMachine vm = new VendingMachine(); String name = vm.getJuiceName(); assertThat(name, is("コーラ")); int price = vm.getJuicePrice(); assertThat(price, is(120)); int stock = vm.getJuiceStock(); assertThat(stock, is(5)); } @Test public void testIsPurchacable() { VendingMachine vm = new VendingMachine(); boolean b = vm.isPurchacable(); assertThat(b, is(false)); vm.throwInto(500); b = vm.isPurchacable(); assertThat(b, is(true)); } @Test public void testPurchace() { VendingMachine vm = new VendingMachine(); vm.throwInto(100); vm.throwInto(10); vm.throwInto(10); Output o = vm.purchace(); assertThat(o.getJuiceCount(), is(1)); assertThat(o.getChange(), is(0)); int total = vm.getTotal(); assertThat(total, is(0)); } }
VendingMachine.java
public class VendingMachine { private int total; public int throwInto(int yen) { if (yen == 1) return 1; if (yen == 5) return 5; if (yen == 2000) return 2000; if (yen == 5000) return 5000; if (yen == 10000) return 10000; total += yen; return 0; } public int getTotal() { return total; } public int refund() { int refund = total; total = 0; return refund; } public String getJuiceName() { return "コーラ"; } public int getJuicePrice() { return 120; } public int getJuiceStock() { return 5; } public boolean isPurchacable() { if (getJuiceStock() == 0) return false; return total >= getJuicePrice(); } public Output purchace() { return new Output(1, 0); } }
Juice.java
public class Juice { private String name; private int price; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } }
500円を投入して購入する。
VendingMachineTest.java
@Test public void testPurchace500() { VendingMachine vm = new VendingMachine(); vm.throwInto(500); Output o = vm.purchace(); assertThat(o.getJuiceCount(), is(1)); assertThat(o.getChange(), is(380)); int total = vm.getTotal(); assertThat(total, is(0)); }
1000円を投入して購入する。
VendingMachineTest.java
@Test public void testPurchace1000() { VendingMachine vm = new VendingMachine(); vm.throwInto(1000); Output o = vm.purchace(); assertThat(o.getJuiceCount(), is(1)); assertThat(o.getChange(), is(880)); int total = vm.getTotal(); assertThat(total, is(0)); }
在庫切れを実装する。
500円を投入して購入する。
VendingMachineTest.java
@Test public void testPurchace500() { VendingMachine vm = new VendingMachine(); vm.throwInto(1000); Output o = vm.purchace(); assertThat(o.getJuiceCount(), is(1)); assertThat(o.getChange(), is(880)); int stock = vm.getJuiceStock(); assertThat(stock, is(4)); for (int i = 0; i < 4; i++) { vm.throwInto(500); o = vm.purchace(); } stock = vm.getJuiceStock(); assertThat(stock, is(0)); vm.throwInto(500); o = vm.purchace(); assertThat(o.getJuiceCount(), is(0)); assertThat(o.getChange(), is(0)); int total = vm.getTotal(); assertThat(total, is(500)); }
売上高を確認できるようにする。
VendingMachineTest.java
@Test public void testSale() { VendingMachine vm = new VendingMachine(); int sale = vm.getSale(); assertThat(sale, is(0)); vm.throwInto(500); vm.purchace(); sale = vm.getSale(); assertThat(sale, is(120)); }