1

Mockito を使用していくつかのことを確認したいのですが、ドキュメントを調べたところ、通常の Mockito ツールの外に出ないとできないことがわかりました。例としてこれを取ります:

DrawTool tool = mock(DrawTool.class);
new Drawer().draw(tool);
verify(tool).begin(); // Make sure begin and end are called exactly once each
verify(tool).end();
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();
inOrder.verifyNoMoreInteractions();

このテストは、それが最後のインタラクションであることの検証など、いくつかのことをうまく検証しflushますが、Mockito にはそれbeginが最初のインタラクションであることを検証する方法がないようです。Mockito のツールの非対称性に驚いたので、カスタム VerificationModes を作成する可能性を調査しています。次のような VerificationMode を作成し、次のようbeforeAnyOtherに使用したいと思います。

inOrder.verify(tool, beforeAnyOther()).begin();
inOrder.verify(tool).end();
inOrder.verify(tool, beforeAnyOther()).flush();
inOrder.verifyNoMoreInteractions();

beginその意図は、 が最初に呼び出され、 と の間に関連する相互作用がないこと、endおよび とのflush間の相互作用が未指定であることを確認することです。beginend

私は既存の VerificationModes のソースコードを研究しており、原則としてこれは実装する単純な VerificationMode であるべきだと思われますが、Mockito のいくつかの主要なクラスを超えると、ドキュメントは非常に薄くなり、まるで私に教えようとしているかのようになります。これらのクラスに触れてはいけません。org.mockito.internalこのような名前は、これらのクラスがパブリックであっても変更される可能性があることを示唆しているため、開始するパッケージには特に注意しています。

VerificationMode を実装するための本当に重要なクラスはすべてorg.mockito.internal.verification.apiパッケージに含まれているようです。そのパッケージ全体には、javadoc が 1 ビットしか含まれていないようで、「検証 API が完全に終了したら、このパッケージを公開する必要があります」と書かれています。それは、このパッケージが積極的に変更されているということなので、含まれているものは何も使用すべきではないということですか? それとも、何年にもわたって言われてきたことであり、パッケージが実際に変更されることはおそらくないのでしょうか?

クラスを使用できない場合、org.mockito.internal.verification.apiカスタム VerificationModes を実装することは不可能のようです。カスタム VerificationModes なしでこのようなことを行う方法はありますか?

4

1 に答える 1

2

モックで発生する一連の呼び出しを完全に指定できる場合は、beforeAnyOther検証モードは必要ありません。たとえば、あなたの望ましい行動が...

  • begin一度呼び出され、その後
  • end一度呼び出され、その後
  • flush一度呼び出される
  • 他の呼び出しは行われませんtool

次に、次のジョブを実行する必要があります。

// Verify that the three invocations arrived in the desired order.
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();

// Verify that the three invocations are all we received.
Mockito.verify(tool).begin();
Mockito.verify(tool).end();
Mockito.verify(tool).flush();
Mockito.verifyNoMoreInteractions();

一方、確認したいシーケンス以外で発生する追加の呼び出しがある場合は、正しいですが、Mockito は現在それを確認できません。したがって、たとえば、 とのtool.setPenColor()間のある時点で呼び出す必要があることがわかっていても、この呼び出しが への呼び出しの前か後かは問題ではない場合、運が悪いでしょう。beginflushend

この状況は、他のいくつかのモック ライブラリで処理できます。EasyMock はこれを簡単にします - 例えば、begin最初にflush来て最後に来るシーケンスの場合、途中の呼び出しは気にしません:

DrawTool mock = EasyMock.createMock(DrawTool.class);
EasyMock.checkOrder(mock, true);
mock.begin();
EasyMock.expectLastCall();
EasyMock.checkOrder(mock, false);
mock.end();
EasyMock.expectLastCall();
EasyMock.expect(mock.someOtherCallThatReturnsAValue()).andReturn(null);
EasyMock.checkOrder(mock, true);
mock.flush();
EasyMock.expectLastCall();
EasyMock.replay(mock);

new Drawer().draw(tool);

EasyMock.verify(mock); 

扱いにくい場合でも、JMock 2 で同等のテストが可能のようです。JMock 1 では少し 簡単ですが、そのライブラリは時代遅れ (JDK 1.3 頃) であるため、使用しないでください。これは Moxie では不可能です (免責事項/恥知らずなプラグイン: 私は作成者です) が、そのためのtodo リスト項目があります。

Mockito の検証 API ドキュメントがなぜこのような形になっているのかについて、Mockito の開発者を代弁することはできません。メーリング リストで質問するのが一番です。彼らはパッチを歓迎すると確信しています。

于 2013-11-01T21:03:37.630 に答える