68

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

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

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

4

5 に答える 5

94

あなたが正しくやりたいことを理解していれば、次を使用できるはずです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 ユーザー ガイドでは、次のように説明されています。

戻り値または例外の作成

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

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

于 2009-05-13T17:20:25.703 に答える
23

呼び出されると予想されるたびに void メソッドを呼び出すだけで、 を呼び出すEasyMock.expectLastCall()前に呼び出すとreplay()、Easymock は各呼び出しを「記憶」します。

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

ありがとうクリス!

仲間の StackOverflow ユーザーBurt Beckwithによる「Fun With EasyMock」</a>は、より詳細な情報を提供する優れたブログ投稿です。注目すべき抜粋:

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

  1. モックを作成する
  2. 予想される呼び出しexpect(mock.[method call]).andReturn([result])ごとに呼び出す
  3. call mock.[method call]、次にEasyMock.expectLastCall()予想されるそれぞれの void 呼び出しに対して
  4. replay(mock)「記録」モードから「再生」モードに切り替えるための呼び出し
  5. 必要に応じてモックを注入する
  6. テストメソッドを呼び出す
  7. 予想されるすべての呼び出しverify(mock)が発生したことを保証するための呼び出し
于 2009-05-13T18:01:20.460 に答える
5

後でパラメーターにアクセスしたいだけなら、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());
于 2012-01-10T18:52:41.173 に答える
-1

このような状況では、単体テスト クラスでネストされたクラスを作成し、その方法で特別な要件を持つメソッドをオーバーライドすることが最善の方法であることがわかりました。したがって、ClassAアクセスする必要があるパラメーターを使用してそのメソッドをテストしている場合は、次のようにします。

class MockClassA extends ClassA {
    @Override
    void specialMethod(String param1, String param2) {
        // do logging or manipulation of some sort
        super.specialMethod(param1,param2); // if you need to
    }
}

単体テスト コードでは、代わりにこのインスタンスを使用します。他のモック オブジェクトであるかのように扱ってください。ライブラリを混在させるよりもはるかに簡単ですが、これはおそらく良い考えではありません。

于 2009-05-13T16:44:02.753 に答える