ほわいとぼーど

ぷろぐらまのメモ帳

jmockitでCapture

こんな感じのクラスがあって、

public class SampleCapture {
	public boolean execute(String input) {
		String processedInput = String.format("input: %s", input);
		boolean success = new SampleMock().accessSomething(processedInput);
		return success;
	}
}

accessSomething()の部分は外部アクセスだったりなのでモック化したいとする。
ただし、その前にロジックが入っているのでモックに対する入力値はチェックしたい。
こんな時はwithCaptureを使います。

public class SampleCaptureTest {
	@Test
	public void testExecuteSuccessfully() {
		final List<String> inputList = new ArrayList<String>();
		new Expectations() {
			@NonStrict
			SampleMock sampleMock;
			{
				sampleMock.accessSomething(withCapture(inputList)); result = true; times = 1;
			}
		};
		
		SampleCapture sut = new SampleCapture();
		boolean actual = sut.execute("test");
		
		assertTrue(actual);
		assertEquals(inputList.get(0), "input: test");
	}
}

前回でjmockitのバージョンを上げた話をしましたが、
このwithCaptureを使いたいためにバージョンをあげました。
最新は1.3まで出ていて、1.1でdeprecatedだったメソッドが削除されていますね。

withCaptureには、上記のwithCapture(java.util.List)の他にも単体のwithCapture()や、
(String age; age = withCapture();のように使う)
withNullやwithAnyのように直接的に比較するメソッドもありますが、
Verificationsの中でのみ使えるものもあり、まだ全然把握できてません。

自分は今のところVerificationsは使ってないです。
大抵は今回のようにチェックもモック化もしたい箇所ばかりで、
Expectationsで呼ぶと同じ箇所はVerificationsでチェックできない?ように見えます。
完全に調べたわけではないですが。



ところで、上記のようなロジック→呼び出し→ロジック→呼び出し
の繰り返しになるようなコードを他の人はどうクラス構成してるんだろう。
ある呼び出しに付随するロジックは、それも含めた呼び出しにすればいいけど、
一部はその後の処理でも使う値があったりすると分けざるをえないし、
そうやってくとクラス内で状態遷移が増えるので
Stateパターンみたいに分割しようとすると今度は大量のデータの受け渡しが・・・

テストを考えたら分割すべきなんでしょうけど、
受け渡すデータが増えるとテストデータ作るのも大変です。
スマートにどうにかしたい・・・ぐぬぬ。