きっかけ
バッチ処理などの、処理の対象となるものをprivateメソッドで取得しているときに、処理対象の条件についてのテストを書きたくなったのがきっかけ。spyとArgumentCaptorをつかえばうまくいきそうとおもい、試してみた。
やり方
テストするコード
Sample.java
public class Sample {
public void execute() {
List<T> targets = getTargets();
execute(targets);
}
private List<T> getTargets() {
/* DBなどから、処理対象となるものを取得 */
}
public void execute(List<T> targest) {
/* 対象のリストを指定しての処理 */
}
}
テストコード
ArgumentCaptorをアノテーションで用意し、テストするクラスのインスタンスをspyに渡します。
そうすると、whenなどで振る舞いを指定しないものについてはもとのままで、それらもverifyで呼び出されたかどうかを確認できます。
:SampleTest.java
public class SampleTest {
@Captor
ArgumentCaptor<List<T>> captor;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
Sample sample = spy(new Sample());
sample.execute();
// captorで #execute(List<T> targets)に渡された引数を取得
verify(sample, times(1)).execute(captor.capture());
List<T> targets = captor.getValue();
T expected = ...;
asssertThat(targets).contains(expected);
}
}
所感
そもそも、処理対象を取得する部分を別のクラスに切り出して、個別にテストする方がよいかもしれない。
ただ、そこまで分けるほどでないときや、関連するをまとめたいようなときには、こういったのも手軽にできてよいかも。