2

私はこの抽象クラスを持っています:

public abstract class Accessor<T extends Id, U extends Value>
{
   public U find(T id)
   {
        // let's say
        return getHelper().find(id);
   }
}

そして実装:

public FooAccessor extends Accessor<FooId,Foo>
{
    public Helper getHelper
    {
        // ...
        return helper;
    }
}

そして、FooAccessor.find への呼び出しをモックしたいと思います。これ:

@MockClass(realClass=FooAccessor.class)
static class MockedFooAccessor
{
    public Foo find (FooId id)
    {
        return new Foo("mocked!");
    }
}

このエラーで失敗します:

java.lang.IllegalArgumentException: Matching real methods not found for the following mocks of MockedFooAccessor:
Foo find (FooId)

理由は理解できますが、他にどうすればよいかわかりません。

注: はい、getHelper メソッドをモックして、必要なものを取得できます。しかし、これは JMockit とこの特定のケースについて学ぶべき問題です。

4

2 に答える 2

2

私が見つけたこれを回避する唯一の方法は、フィールドを使用することです

@Test
public void testMyFooMethodThatCallsFooFind(){
MyChildFooClass childFooClass = new ChildFooClass();
String expectedFooValue = "FakeFooValue";
new NonStrictExpectations(){{
 setField(childFooClass, "fieldYouStoreYourFindResultIn", expectedFooValue);
}};

childFooClass.doSomethingThatCallsFind();

// if your method is protected or private you use Deencapsulation class 
// instead of calling it directly like above
Deencapsulation.invoke(childFooClass, "nameOfFindMethod", argsIfNeededForFind);
// then to get it back out since you used a field you use Deencapsulation again to pull out the field
String actualFoo = Deencapsulation.getField(childFooClass, "nameOfFieldToRunAssertionsAgainst");

assertEquals(expectedFooValue ,actualFoo);

}

childFooClassをモックする必要はなく、親をモックする必要もありません。

あなたの特定のケースについての知識がなくても、この戦略は私がjMockit Deencapsulationを活用するための最良の方法であり、可視性を犠牲にすることなく多くのことをテストすることができます。私はこれが直接の質問に答えないことを知っていますが、あなたはそれから何かを得るべきだと感じました。気軽に反対票を投じて、私コミュニティを非難してください。

于 2013-02-21T20:10:05.560 に答える
2

正直なところ、通常のクラスを嘲笑するのと何ら変わりはありません。find1 つの方法は、メソッドのみをモックし、Expectationsブロックを使用して別の実装を提供するように JMockit に指示することです。このような:

abstract class Base<T, U> {
    public U find(T id) {
        return null;
    }
}

class Concrete extends Base<Integer, String> {
    public String work() {
        return find(1);
    }
}

@RunWith(JMockit.class)
public class TestClass {

    @Mocked(methods = "find")
    private Concrete concrete;

    @Test
    public void doTest() {

        new NonStrictExpectations() {{
            concrete.find((Integer) withNotNull());
            result = "Blah";
        }}

        assertEquals("Blah", concrete.work());
    }
}

それが役に立てば幸い。

于 2013-02-26T17:31:05.677 に答える