MusicPlayerのテストを追加する。
以下のテストコードを追加する。
@Test
void 新規プレイリストに音楽を追加する() {
MusicPlayer mp = new MusicPlayer();
mp.addMusicToPlayList("お気に入り", "Official髭男dism", "パラボラ");
int n = mp.countMusic();
assertEquals(1, n);
n = mp.countPlayList();
assertEquals(1, n);
PlayList p = mp.getPlayList(0);
assertNotNull(p);
assertEquals("お気に入り", p.getName());
Music m = p.getMusic(0);
assertEquals("パラボラ", m.getTitle());
}
音楽プレイヤーの新しい機能を思いつかないので、別の課題にすすみましょう。
自動販売機クラス
TDDBC大阪の課題として出された自動販売機をやってみましょう。
TDD Boot Camp 大阪 2.0/課題( #tddbc )
新規Javaプロジェクト「vendingmachine」を作成する。
vendingmachineプロジェクトに VendingMachineクラスを作成する。
package jp.abc;
/**
* 自動販売機クラス
* @author satoshis
*
*/
public class VendingMachine {
}
まずは「お金を投入する」機能を追加する。
投入するだけではどうなっているのかがわからないので、投入済みの金額を取得できるようにする。
package jp.abc;
/**
* 自動販売機クラス
* @author satoshis
*
*/
public class VendingMachine {
public void put(int i) {
}
public int entered() {
return 0;
}
}
package jp.abc;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class VendingMachineTest {
@Test
void お金を投入する() {
VendingMachine vm = new VendingMachine();
vm.put(10);
int m = vm.entered();
assertEquals(10, m);
}
}
10円投入後に50円を投入する動作をテストで作ってみる。
@Test
void お金を投入する() {
VendingMachine vm = new VendingMachine();
vm.put(10);
int m = vm.entered();
assertEquals(10, m);
vm.put(50);
m = vm.entered();
assertEquals(60, m);
}
このテストにパスするように、VendingMachineを実装する。
package jp.abc;
/**
* 自動販売機クラス
* @author satoshis
*
*/
public class VendingMachine {
private int total = 0;
public void put(int money) {
total += money;
}
public int entered() {
return total;
}
}
次の課題として、お金を払い戻す機能を追加する。
そのために、テストを作成する。
@Test
void お金を払い戻す() {
VendingMachine vm = new VendingMachine();
vm.put(500);
int m = vm.entered();
assertEquals(500, m);
m = vm.refund();
assertEquals(500, m);
}
コンパイルエラーを解消するために、VendingMachineクラスにrefund()メソッドを追加する。
package jp.abc;
/**
* 自動販売機クラス
* @author satoshis
*
*/
public class VendingMachine {
private int total = 0;
public void put(int money) {
total += money;
}
public int entered() {
return total;
}
public int refund() {
return 0;
}
}
fakeでテストにパスさせる。
public int refund() {
return 500;
}
テストを追加する。
払い戻し後は投入金額が0円になる。
@Test
void お金を払い戻す() {
VendingMachine vm = new VendingMachine();
vm.put(500);
int m = vm.entered();
assertEquals(500, m);
m = vm.refund();
assertEquals(500, m);
m = vm.entered();
assertEquals(0, m);
}
テストにパスするように自動販売機クラスを修正する。
public int refund() {
total = 0;
return 500;
}
テスト駆動開発のススメ方。
- 新しい機能に対するテストを作る→コンパイルエラーになる
- 新しいメソッドを作ってコンパイルエラーを解消する
- コンパイルエラーを解消できたらテストを実行する→エラーになる
- Fakeの実装でテストをパスさせる
- Fakeではパスできないテストを追加する→エラーになる
- 追加したテストにもパスするように修正する→パスする
お金を払い戻すテストに2回めのお金の投入と払い戻しを行う。
@Test
void お金を払い戻す() {
VendingMachine vm = new VendingMachine();
vm.put(500);
int m = vm.entered();
assertEquals(500, m);
m = vm.refund();
assertEquals(500, m);
m = vm.entered();
assertEquals(0, m);
vm.put(100);
m = vm.entered();
assertEquals(100, m);
m = vm.refund();
assertEquals(100, m);
}
テストがエラーに鳴るので、refund()メソッドを修正する。
public int refund() {
int r = total;
total = 0;
return r;
}
ステップ1
想定外のお金が投入されたら、投入金額に加算せずにそのまま払い戻す。
テストを追加する。
@Test
void 想定外のお金を投入() {
VendingMachine vm = new VendingMachine();
vm.put(5);
int m = vm.entered();
assertEquals(0, m);
}
1円から10000円までの全部をテストするコードを追加する。
@Test
void 想定外のお金を投入() {
VendingMachine vm = new VendingMachine();
vm.put(5);
int m = vm.entered();
assertEquals(0, m);
vm.put(1);
m = vm.entered();
assertEquals(0, m);
for (int i = 1; i <= 10000; i++) {
vm.put(i);
m = vm.entered();
if (i == 10 || i == 50 || i == 100 || i == 500 || i == 1000) {
assertEquals(i, m);
} else {
assertEquals(0, m);
}
vm.refund();
}
}