以下の記事をベースに話を進めていきます。
ユニットテストという監査人
システム概要
仕様1.部下Aと部下Bの仕事だ正しいか監査する
仕様2.上司が部下Aと部下Bに仕事をさせているか監査する
監査前
部下Aは、商品名からケース当たりの本数を報告する。
部下Bは、発注数とケース当たりの本数から合計本数を計算する。
上司は、やってきた部下たちに指示を出して結果を報告する。
上司.java
class 上司 {
public int 合計本数の確認の指示を出す{
部下A 太郎, 部下B 花子,
String 商品名, int 発注数){
int ケース当たりの本数 = 太郎.ケース当たりの本数の報告(商品名);
int 合計本数 = 花子.合計本数の計算(ケース当たりの本数, 発注数);
return 合計本数;
}
}
部下A.java
class 部下A {
public int ケース当たりの本数の報告(String 商品名){
if(商品名.equals("コーラ")){
return 12;
}
if(商品名.equals("サイダー")){
return 24;
}
return 20;//他は20本
}
}
部下B.java
class 部下B {
public int 合計本数の計算(int ケースあたりの本数, int 発注数){
return ケース当たりの本数 * 発注数;
}
}
部下の監査
部下Aと部下Bが想定通りなのか監査する。
パターンが固定数のものは可能な限り監査する。
パターンが出せないものは最低2パターンは監査する。
監査員.java
public class 監査員 {
@Test
public void 部下Aに関する監査() {
部下A 太郎 = new 部下A();
assertEquals(太郎.ケース当たりの本数の報告("コーラ"), 12);
assertEquals(太郎.ケース当たりの本数の報告("サイダー"), 24);
assertEquals(太郎.ケース当たりの本数の報告("紅茶"), 20);
}
@Test
public void 部下Bに関する監査() {
部下B 花子 = new 部下B();
assertEquals(花子.合計本数の計算(12, 3), 36);
assertEquals(花子.合計本数の計算(24, 2), 48);
}
部下A.java
~省略~
部下B.java
~省略~
上司への監査
部下の動きはすでに監査済みなので、上司の監査で部下が正しい動きなのか把握する必要はない。
監査員.java
public class 監査員 {
@Test
public void 上司に関する監査() {
上司 斎藤 = new 上司();
部下A 太郎 = new 部下A();
部下B 花子 = new 部下B();
assertEquals(斎藤.合計本数の確認の指示を出す(太郎,花子, "コーラ", 10), 120);
上司 斎藤 = new 上司();
部下A 太郎 = new 部下A();
部下B 花子 = new 部下B();
assertEquals(斎藤.合計本数の確認の指示を出す(太郎,花子, "紅茶", 3), 60);
}
@Test
public void 部下Aに関する監査() {
部下A 太郎 = new 部下A();
assertEquals(太郎.ケース当たりの本数の報告("コーラ"), 12);
assertEquals(太郎.ケース当たりの本数の報告("サイダー"), 24);
assertEquals(太郎.ケース当たりの本数の報告("紅茶"), 20);
}
@Test
public void 部下Bに関する監査() {
部下B 花子 = new 部下B();
assertEquals(花子.合計本数の計算(12, 3), 36);
assertEquals(花子.合計本数の計算(24, 2), 48);
}
部下A.java
~省略~
部下B.java
~省略~
覆面調査員(モックオブジェクト)
Aになりきった覆面調査員が常に50を返すことで部下Bへの指示が正しいか監査する。
Bになりきった覆面調査員が20を渡されたときにだけ128を渡すことで部下Aへの指示が正しいか監査する。
監査員.java
public class 監査員 {
@Test
public void 上司に関する監査() {
上司 斎藤 = new 上司();
部下A 太郎 = new 部下A();
部下B 花子 = new 部下B();
assertEquals(斎藤.合計本数の確認の指示を出す(太郎,花子, "コーラ", 10), 120);
上司 斎藤 = new 上司();
部下A 太郎 = new 部下A();
部下B 花子 = new 部下B();
assertEquals(斎藤.合計本数の確認の指示を出す(太郎,花子, "紅茶", 3), 60);
}
@Test
public void 上司に関する覆面A調査員を使っての監査() {
上司 斎藤 = new 上司();
部下A 覆面太郎 = mock(部下A.class);
when(覆面太郎.ケース当たりの本数の報告(anyString())).thenReturn(50);
部下B 花子 = new 部下B();
assertEquals(斎藤.合計本数の確認の指示を出す(太郎,花子, "紅茶", 6), 300);
}
@Test
public void 上司に関する覆面B調査員を使っての監査() {
上司 斎藤 = new 上司();
部下A 太郎 = new 部下A();
部下B 覆面花子 = mock(部下B.class);
when(覆面花子.合計本数の計算(20)).thenReturn(128);
assertEquals(斎藤.合計本数の確認の指示を出す(太郎,花子, "紅茶", 6), 128);
}
@Test
public void 部下Aに関する監査() {
部下A 太郎 = new 部下A();
assertEquals(太郎.ケース当たりの本数の報告("コーラ"), 12);
assertEquals(太郎.ケース当たりの本数の報告("サイダー"), 24);
assertEquals(太郎.ケース当たりの本数の報告("紅茶"), 20);
}
@Test
public void 部下Bに関する監査() {
部下B 花子 = new 部下B();
assertEquals(花子.合計本数の計算(12, 3), 36);
assertEquals(花子.合計本数の計算(24, 2), 48);
}
部下A.java
~省略~
部下B.java
~省略~
覆面調査員についてはもう少し、精査を予定しています。