とある日、こんなコードを書いてました
@Inject
private Accessor accessor;
@Dependent
public class DataReader {
String getData(String key) {
String value = accessor.getByDate(key, new Date());
return value;
}
}
さあテストだぜ! と思って書いたテストがこちら
public class DataReaderTest {
@Mock
Accessor accessor;
@InjectMocks @Spy
DataReader dataReader;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
when(accessor.getByDate(key, new Date())).thenReturn(now);
assertThat(dataReader.getData("key0"), is("todayData"));
}
}
しかし成功しない...と相談したところ、「これは成功しないよね、テストしづらいし。」ということで以下のように修正
Testのwhen(accessor.getByDate(key, new Date())).thenReturn(now);
と実際に呼び出すaccessor.getByDate(key, getNow())
ではDate型の引数の値が変わってしまうため失敗していました
修正後
@Inject
private Accessor accessor;
@Dependent
public class DataReader {
String getData(String key) {
String value = accessor.getByDate(key, getNow());
return value;
}
Date getNow() {
return new Date();
}
}
public class DataReaderReaderTest {
@Mock
Accessor accessor;
@InjectMocks @Spy
DataReader dataReader;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
Date now = new Date();
//こちらでも良い
//when(deviceOptionReader.getNow()).thenReturn(now);
doReturn(now).when(deviceOptionReader).getNow();
when(accessor.getByDate(key, now)).thenReturn(now);
assertThat(dataReader.getData("key0"), is("todayData"));
}
}
戒め
メソッドの引数に直接Date型をnewするようなコードを書いてはならない