何もメソッドの後に呼び出されていないことを確認するために、Mockitoを使用
-
21-08-2019 - |
質問
私は、Javaでのユニットテストを書くことMockitoを使用している、と私は特定の方法は、のオブジェクトで呼び出さの最後のものであることを確認したいと思います。
私は、テスト対象のコード内でこのような何かをやってます:
row.setSomething(value);
row.setSomethingElse(anotherValue);
row.editABunchMoreStuff();
row.saveToDatabase();
私のモックでは、私は、行上のすべてを編集する順番を気にしないが、それは私がをすることが非常に重要ですの私が保存した後にさらに何かをしようとしませんそれ。これを行うには良い方法はありますか?
私はverifyNoMoreInteractionsを探していないよということに注意してください:それはsaveToDatabaseと呼ばれる最後のものであることを確認していない、と私は明示的に検証していない行に何かを呼び出した場合、それも失敗します。私のような何かを言うことができるようにしたいと思います:
verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verifyTheLastThingCalledOn(row).saveToDatabase();
それが助け場合は、、私はこれをしなかったJMockテストからMockitoに切り替えています:
row.expects(once()).method("saveToDatabase").id("save");
row.expects(never()).method(ANYTHING).after("save");
解決
私はそれがより多くのカスタム作業が必要だと思います。
verify(row, new LastCall()).saveToDatabase();
し、
public class LastCall implements VerificationMode {
public void verify(VerificationData data) {
List<Invocation> invocations = data.getAllInvocations();
InvocationMatcher matcher = data.getWanted();
Invocation invocation = invocations.get(invocations.size() - 1);
if (!matcher.matches(invocation)) throw new MockitoException("...");
}
}
前の回答:
あなたは正しいです。 verifyNoMoreInteractions何が必要です。
verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verify(row).editABunchMoreStuff();
verify(row).saveToDatabase();
verifyNoMoreInteractions(row);
他のヒント
100%ではないけど、私はただ検証の反対を見つけるために探していた、そしてこれが唯一の関連する結果であった、それは私がMockito.verifyZeroInteractions(モック)後のことでした終わる;
誰がこれを見て、ここで終わるだけで包み...
この質問は JMockitにのた検証のAPIにいくつかの機能強化をするために私を導きました(今後のリリース0.983で利用可能)するます。
私が思いついた解決策は、あなたが(試験方法で)記述することができます:
new VerificationsInOrder() {{
unverifiedInvocations();
row.saveToDababase();
}};
...あなただけの特定の方法は、他のすべての後に呼び出されていることを確認したい場合。それはの前にの他のすべての呼び出しをたまたま確認するには、単にトップへの呼び出しを移動します。これは実際には連続した呼び出しの任意のシーケンスに適用されます。
上記の検証に加えて、あなたはまた、いくつかの他の方法は、任意の順序で呼び出されていることを確認したい場合は、、2番目のの検証のブロックは他のブロックの前または後(テストに追加することができます、それは)問題ではありません。
new Verifications() {{
row.setSomething(value);
row.setSomethingElse(anotherValue);
}};
長いので、匿名の内部クラスの使用のビットは、この構文は、簡単で柔軟両方であるが。それはテストに構造を追加し、(verify(...)
のような)メソッド呼び出しの繰り返しを回避する方法に注目してください。私は(Hamcrestは、呼び出し回数などをマッチャー)、そしてそれは(静的メソッドとコンストラクタは嘲笑と同じ方法で確認することができます)。