This is a cache of http://qiita.com/syamozi/items/ebb203cd5ad4bc1020dd. It is a snapshot of the page at 2017-09-17T03:11:50.359+0900.
【Java初心者の苦悩】Junitで実装してしまった<strong>テスト</strong>しにくいコード - Qiita

【Java初心者の苦悩】Junitで実装してしまったテストしにくいコード

  • 3
    いいね
  • 3
    コメント

とある日、こんなコードを書いてました

@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するようなコードを書いてはならない