mockitoが動かない!(とりあえず動いた編)
前回はmockitoが動かない問題だけを紹介したので、とりあえずの解決編。
問題は残ってるんだけど。。。
方針としては、モックオブジェクトのwriteメソッドを偽装してメソッドが呼び出された時の引数を別のオブジェクトに格納しておくよ。
返り値のないメソッドを偽装するときにはdoAnswerを利用する。
final List<Map<Text, Text>> realInvocation = new ArrayList<Map<Text,Text>>(); doAnswer(new Answer<Object>() { public Object answer(InvocationOnMock invocation) throws Throwable { Text invocedKey = (Text) invocation.getArguments()[0]; Text invocedValue = (Text) invocation.getArguments()[1]; Text key = new Text(Arrays.copyOfRange(invocedKey.getBytes(), 0, invocedKey.getLength())); Text value = new Text(Arrays.copyOfRange(invocedValue.getBytes(), 0, invocedValue.getLength())); Map<Text, Text> savedInvocation = new HashMap<Text, Text>(); savedInvocation.put(key, value); realInvocation.add(savedInvocation); return null; } }).when(mockContext).write(any(Text.class), any(Text.class));
こんな感じでwriteメソッドが呼び出された時に、引数をちゃんとコピーして、自分の用意したListの中に格納する。
Listに格納しちゃうので、確認方法も修正
assertEquals(realInvocation.get(0).get(new Text("0")), new Text("0")); assertEquals(realInvocation.get(1).get(new Text("1")), new Text("1")); assertEquals(realInvocation.get(2).get(new Text("2")), new Text("2")); assertEquals(realInvocation.get(3).get(new Text("3")), new Text("3")); assertEquals(realInvocation.get(4).get(new Text("4")), new Text("4"));
コレでテストが通るようになる。
問題点としては、モックオブジェクトの呼び出しに対しては確認を行ってないので、verifyNoMoreInteractionsを実行するとこけてしまうこと。
自分でオブジェクトを用意して格納するのではなく、mockitoの保存しているInvocationを上書きできれば良いんだけれど、まだよくわかってない。