web-dev-qa-db-ja.com

EasyMock:Voidメソッド

テストするクラスの依存関係であるクラスにvoidを返すメソッドがあります。

このクラスは巨大であり、この単一のメソッドのみを使用しています。テストでこのメソッドの実装を置き換えて、何か別のことをしたいので、このメソッドが受け取るパラメーターにアクセスできるようにする必要があります。

EasyMock でこれを行う方法が見つかりません。 doAnswer を使用して Mockito でそれを行う方法を知っていると思いますが、絶対に必要でない限り、別のライブラリを追加したくありません。

68
Iker Jimenez

あなたが正しくやりたいことを理解したら、andAnswer()を使用できるはずです:

mockObject.someMethod(eq(param1), eq(param2));
expectLastCall().andAnswer(new IAnswer() {
    public Object answer() {
        //supply your mock implementation here...
        SomeClass arg1 = (SomeClass) getCurrentArguments()[0];
        AnotherClass arg2 = (AnotherClass) getCurrentArguments()[1];
        arg1.doSomething(blah);
        //return the value to be returned by the method (null for void)
        return null;
    }
});

EasyMock User Guide の説明:

戻り値または例外の作成

モックオブジェクトが値を返すか、実際の呼び出し時に作成された例外をスローするようにしたい場合があります。 EasyMock 2.2以降、 expectLastCall() および expect(T value) によって返されるオブジェクトは、メソッド andAnswer(IAnswer answer) を提供します=これにより、インターフェイスの実装を指定できるようになります IAnswer 戻り値または例外の作成に使用されます。

IAnswer コールバック内で、模擬呼び出しに渡される引数は EasyMock.getCurrentArguments() を介して利用できます。これらを使用すると、パラメーターの並べ替えなどのリファクタリングによりテストが中断される場合があります。あなたは警告されました。

91
matt b

Voidメソッドを呼び出すたびにvoidメソッドを呼び出し、EasyMock.expectLastCall()を呼び出す前にreplay()を呼び出すと、Easymockは各呼び出しを「記憶」します。

そのため、呼び出し以外はvoidメソッドから何も期待していないので、expect()lastCall以外)を明示的に呼び出す必要はないと思います。

クリスありがとう!

「EasyMockで楽しむ」 StackOverflowの仲間のユーザーによる Burt Beckwith は、より詳細なブログ投稿です。注目すべき抜粋:

基本的に私が使用する傾向があるフローは次のとおりです。

  1. モックを作成する
  2. 予想される各呼び出しに対してexpect(mock.[method call]).andReturn([result])を呼び出します
  3. _mock.[method call]_を呼び出してから、予想される各void呼び出しに対してEasyMock.expectLastCall()を呼び出します
  4. replay(mock)を呼び出して、「記録」モードから「再生」モードに切り替えます。
  5. 必要に応じてモックを注入する
  6. テストメソッドを呼び出す
  7. verify(mock)を呼び出して、予想されるすべての呼び出しが行われたことを確認します
22

後で使用するためにのみパラメーターにアクセスする場合は、EasyMock 2.4で新しく追加された Captures クラスもお勧めします。

マッチャーの代わりに「Capture」クラスのインスタンスを使用できます。モックされたメソッドが呼び出されると、Captureインスタンスは呼び出されたパラメーターを保存します。

Capture<ChartPanel> captured = new Capture<ChartPanel>();
// setChartPanel is going to be called during execution;
// we want to verify some things about the ChartPanel
// instance it's invoked with
chartMock.setChartPanel(capture(captured));
replay(chartMock);

ufdm.setChartAnnotater(chartMock);
// afterPropertiesSet triggers the setChartPanel call...
ufdm.afterPropertiesSet();
verify(chartMock);

// verify some things about the ChartPanel parameter our
// mock object was invoked with
assertSame(plot, captured.getValue().getChart().getPlot());
5
piepera

PowerMockをチェックしてみてください。 EasyMockは、プロキシリフレクションAPIに基づいています。つまり、すべてがプロキシであり、テストできるのはインターフェイスのみであり、最終的なメソッドとクラスのみをテストできます。これは一部の人には有効かもしれませんが、構築された世界をテストする場合は、より多くのパワーが必要になります。

PowerMockでは、Java 5インストルメンテーションAPIが制限を取り除きます。テスト対象のオブジェクトのモックオブジェクト実装を書く必要はありません((いIMO)。PowerMockとMockito(またはJMockit)を組み合わせれば、本当にレースに出かけます。

もちろん、より簡単にテストできるようにコードを書き換える他の方向もあります。これは、可能であれば一般的には良いアイデアです。

1
Joseph Lust