2

私が所有していない別のクラスを拡張するクラスがあります。私のクラスは、親クラスへの多くの呼び出しのいくつかに関するメトリックを計算するために使用されます。単体テストで(子のロジックを保持しながら)親クラスをモックして、子に対して行われた呼び出しが常にラップされた親に「成功する」ようにする方法はありますか?

コード内

Class SlowClass {
    public Object doFoo(Object obj) {
        //...
    }
    public Object doBar(Object obj) {
        //...
    }

    // Many more methods I don't care about.

}

Class SlowClassWrapper extends SlowClass {
    public Object doFoo(Object obj) {
        //...
        Object toReturn = super.doFoo(obj)
        //...
        return toReturn;
    }
    public Object doBar(Object obj) {
        //...
        Object toReturn = super.doFoo(obj)
        //...
        return toReturn;
    }
}

実際に電話をかけずに親に電話をかけるSlowClass.doFooように、どういうわけかモックアウトしたいと思います。次に、それがそのまま通過し、からの応答がそのまま戻ってくるSlowClassWrapper.doFooことを確認したいと思います。objSlowClass.doFoo

4

2 に答える 2

4

一般に、これはフレームワークのモックが Java で満足に実行できるものではありません。継承の代わりに構成を使用するようにコードを再構築することを検討することをお勧めします。次に、SlowClass インスタンスをラッパーのコンストラクターに挿入して、通常のモックで簡単にテストできるようにします。

価値があることについては、Mockito も PowerMock もスーパー メソッドをモックできません。この回答このディスカッションを参照してください。

于 2012-11-14T06:47:44.367 に答える
1

私はそのようなことをします:

public class SlowClassWrapper {
    /** wrapped parent */
    public final SlowClass parent;

    public SlowClassWrapper() {
        this(new SlowClass());

    @VisibleForTesting
    protected SlowClassWrapper(SlowClass parent) {
        this.parent = parent;
    }

    public Object doFoo(Object obj) {
        //...
        Object toReturn = parent.doFoo(obj)
        //...
        return toReturn;
    }

    public Object doBar(Object obj) {
        //...
        Object toReturn = parent.doFoo(obj)
        //...
        return toReturn;
    }
}

Mockitoと JUnit の使用

@RunWith(MockitoJUnitRunner.class)
public class SlowClassWrapperTest {
     /** parent mock */
     @Mock
     private SlowClass parentMock;

     /** instance under tests */
     private SlowClassWrapper instance;

     @Before
     public void setUp() {
         this.instance = new SlowClassWrapper(this.parentMock);
     }

     @Test
     public void testDoFoo() {
         final Object obj1 = new Object();
         final Object obj2 = new Object();
         Mockito.doReturn(obj2).when(this.parentMock).doFoo(Matchers.any());
         assertEquals(obj2, this.instance.doFoo(obj1));
         Mockito.verify(this.parentMock).doFoo(obj1);
         Mockito.verifyNoMoreInteractions(this.parentMock);
     }

     @Test
     public void testDoBar() {
         final Object obj1 = new Object();
         final Object obj2 = new Object();
         Mockito.doReturn(obj2).when(this.parentMock).doBar(Matchers.any());
         assertEquals(obj2, this.instance.doBar(obj1);
         Mockito.verify(this.parentMock).doBar(obj1);
         Mockito.verifyNoMoreInteractions(this.parentMock);
     }
}

(未検証)

于 2012-11-14T06:54:37.183 に答える