どのように私はJMockitで、一般的なオブジェクトとメソッドを模擬するのですか?

StackOverflow https://stackoverflow.com/questions/504332

質問

どのように私はそれにジェネリックを持っている方法を模擬します。

この質問は、あなたがJMockitを使用する方法を知っていれば自明ですか?私はこの方法モックとしたい:(Tエンティティ)保存公共Tを、それは常にこのように例外をスローします:

mockit.RealMethodNotFoundForMockException: Corresponding real methods not found for the following mocks:
Object save(Object)
    at mockit.internal.RedefinitionEngine.modifyRealClass(RedefinitionEngine.java:130)
    at mockit.internal.RedefinitionEngine.modifyRealClass(RedefinitionEngine.java:88)
    at mockit.internal.RedefinitionEngine.redefineMethods(RedefinitionEngine.java:72)
    at mockit.Mockit.setUpMocks(Mockit.java:197)
    at com.mytest.MyTest.setUp(AdminManagerImplTest.java:83)
役に立ちましたか?

解決

それは私のために動作しない、たとえば

package a;

import junit.framework.TestCase;
import mockit.Mockit;

public class JMockitCoreExampleTest extends TestCase {

    public class MockMe {
        public T save(T t) {
            return null;
        }
    }

    public void testDoOperationAbc() {
        Mockit.redefineMethods(MockMe.class, SayThatYouMockMe.class);
                MockMe mock = new MockMe();
        System.out.println(mock.save("aaa"));
    }

    public static class SayThatYouMockMe {
        public T save(T t) {
            return t;
        }
    }
}

出力

Loaded external tool: mockit.integration.junit3.JUnitTestCaseDecorator
Loaded external tool: mockit.integration.junit4.JUnit4ClassRunnerDecorator
aaa

多分あなたは、メソッドを保存するのを休止状態からかっていますか?そうjmockitのhibernate3emul.jarを使用してみた場合、

他のヒント

ただ、完全を期すために:

私は、クラスの中-法モックアップ<...>を使用して、Javaの1.6モードでJava 1.7、TestNGのとjMockit 1.5と1.16と同様の問題がありました。

私のクラスます:

public class MyCache extends AbstractLazyCache<ExchangeObject> {...}

モックメソッドます:

 public abstract class AbstractLazyCache<CachedObject> extends AbstractCache {
      // ...

      protected void putCachedObject(String tenantId, String objectId, CachedObject o, Date expiryDate) {...}
  }

オリジナルモック試みます:

    new MockUp<MyCache>() {
        // invoked once manually, once on expired cache
        @Mock(invocations = 2)
        public void putCachedObject(Invocation inv, String tenantId, String objectId,
                RangeExchange o, Date expiryDate) {
            // expire one second in the future
            inv.proceed(tenantId, objectId, o, new Date(System.currentTimeMillis() + waitTimeMillis));
        }
    };

私は、同様の例外が発生しました。公共の後の追加の一般的なパラメータを追加することで、私のテストケースは、最終的に成功ます:

    new MockUp<MyCache>() {
        // invoked once manually, once on expired cache
        @Mock(invocations = 2)
        public <RangeExchange> void putCachedObject(Invocation inv, String tenantId, String objectId,
                RangeExchange o, Date expiryDate) {
            // expire one second in the future
            inv.proceed(tenantId, objectId, o, new Date(System.currentTimeMillis() + waitTimeMillis));
        }

    };

私はここにあなたの問題はあなたのジェネリック型シグネチャは、あなたがモックしようとしている方法と一致しないことかもしれないと思います。ジェネリック型情報は実行時に利用できないので、JMockitのみジェネリック型情報の消去に起因する方法を見ていることに留意してください。

たとえば、次のシグネチャがあるとします:

public <T> void foo(T param) {
  ...
}

コンパイラはこれを翻訳します

public void foo(Object param) {
  ...
}

これは、バイトコードに表示されて署名され、かつ反射によって何JMockitを見るでしょう。

これに対し、次の署名

public <T extends Map> foo(T param) {
  ...
}

に消去します:

public void foo(Map param) {
  ...
}
実際のクラスが第二を使用しているが、例えば、あなたのモック実装は最初の署名を使用する場合は、

は、根本的な消去が一致しないように、とJMockitは方法を見つけることができないだろう。

http://today.javaを参照してください。ネット/パブ/ A /今日/ 2003/12月2日/ explorations.html の詳細は

たぶん、あなたは私が持っていた同じ星座を持っています:

私は<T> T merge(T t)でモックメソッドorg.hibernate.ejb.EntityManagerImplしようとしたと同じMockitエラーを得ました。

Mockit.redefineMethods(EntityManagerImpl.class, EntityManagerImplMock.class);

私のせいではマージ方法がorg.hibernate.ejb.EntityManagerImplではなく、そのスーパークラスのAbstractEntityManagerImplに宣言されていないということでした。今、私が持っている

Mockit.redefineMethods(AbstractEntityManagerImpl.class, EntityManagerImplMock.class);

タグ付き
public static class EntityManagerImplMock {
    public <T> T merge(final T o) {
        // nothing
        return o;
    }
}

とすべてがうまく動作します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top