7

私のモッククラスでは、メソッド foo() をモックしています。一部のテスト ケースでは、foo() のモック実装が特別な値を返すようにします。他のテスト ケースでは、foo() の実際の実装を使用したいと考えています。モッククラスでブール値を定義して、特別な値を返すか、「実際の」メソッドを使用するかをモックメソッドで決定できるようにします。問題は、モックされたメソッドから実際のメソッドを呼び出す方法がわからないことです。

「it」という名前のモックオブジェクト内に特別なメンバーを定義できることがわかりました(オブジェクトのタイプがモックされています)。これにより、モック実装から実際のクラスを参照できます。したがって、私の計画では、foo() の「実際の」実装を呼び出す必要がある場合は、モック メソッドで it.foo() を呼び出すというものでした。ただし、 it.foo() を呼び出すと、実際のバージョンではなくモックバージョンが再度呼び出されるため、これは機能しません。そのため、無限再帰が発生します。

これを機能させる方法はありますか?

編集:コード例でより明確になる可能性があります。現在のモックされたメソッドの実装は次のようになります。

private RealClass it;
...
public SomeClass foo() {
    if(fakeIt) {
        return new SomeClass("fakevalue");
    } else {
        // doesn't work, just keeps calling the mock foo
        // in infinite recursion
        return it.foo();
    }
}

編集 2: また、ほとんどのテスト ケースでは、モックの実装は必要ありません。したがって、これに対する私の最初の試みは、モック オブジェクトが必要なテスト ケース内でのみ Mockit.redefineMethods() を呼び出すことでした。しかし、これはうまくいきませんでした-セットアップ/ティアダウン内でのみこれを行うことができるようです...私がそれを試したときに、私のモック実装は決して呼び出されませんでした.

解決策に関する注意事項:

最初は、与えられた答えがうまくいくとは思いませんでしたが、もう少し試してみると、JMockit の「コア」メソッドと「注釈」駆動のメソッドを混在させていたことが問題のようです。どうやら注釈を使用するときは、Mockit.redefineMethods() ではなく、Mockit.setupMocks を使用する必要があります。これが最終的に機能したものです:

@Before 
public void setUp() throws Exception
{
    Mockit.setUpMocks(MyMockClass.class);
}

次に、モック クラスの場合:

@MockClass(realClass = RealClass.class)
public static class MyMockClass {
    private static boolean fakeIt = false;
    private RealClass it;

    @Mock(reentrant = true)
    public SomeClass foo() {
        if(fakeIt) {
            return new SomeClass("fakevalue");
        } else {
            return it.foo();
        }
    }
}
4

3 に答える 3

12

JMockit の最近のバージョンでは、実装Invocation.proceed()内から呼び出すことができます。呼び出しコンテキストへのアクセスMockUpを参照してください。

public class MyMockClass extends MockUp<RealClass> {

    private static boolean fakeIt = false;

    @Mock
    public SomeClass foo(Invocation inv) {
        if (fakeIt) {
            return new SomeClass("fakevalue");
        } else {
            return inv.proceed();
        }
    }
}
于 2015-06-10T01:06:33.233 に答える
8

@Mock注釈でこれを行うことができると思います。ドキュメントから、@Mock(reentrant=true)モッククラスでそれを行う必要があります。

http://jmockit.googlecode.com/svn/trunk/www/javadoc/mockit/Mock.html 参照
_ #再入可能

私はこれをテストしていませんが..

于 2008-12-11T04:14:55.413 に答える
1

モック オブジェクトをスローする代わりに、テストしたいオブジェクトをサブクラス化し、特別な値を返すメソッドをオーバーライドすることもできます。

例えば:

RealClass toTest = new RealClass(){
      public String foo(){
          return "special value";
      }
}

//use toTest in test

この定義をテスト内に保持することにより、どのメソッドが「モック」されているかが他の人にも明確になります。

于 2008-12-10T20:07:27.363 に答える