4

Mockitoに問題があります。

そのようなことをすることは可能ですか?

ClassX x = mock(ClassX.class)
when(x.methodB()).thenReturn("toto");
String result = x.methodA();

私はMockito1.7を使用しています。

「スパイ」システムがあるのを見ましたが、テストするアイテムにそれを使用することは推奨されていないと言われています(なぜですか?)。

とにかくそのスパイ機能を試しましたが、奇妙な動作をします。

私がやりたいことを確認してください:

実際のコード:

String methodA(String arg) {
    return this.methodB(arg);
}

String methodB(String arg) {
    return "toto";
}

テストコード:

@Test
public void testTest() {
    final ClassX x = spy( new ClassX() );
    final String argument = "arg";
    doReturn("good").when(helper).methodB(argument);
    assertTrue(  x.methodB(argument).equals("good") );
    assertTrue(  x.methodA(argument).equals("good") );
}  

彼らが言ったように、私はスパイで問題になる可能性のあるwhen thenReturn構文を避けました(しかし、それはとにかく機能しません)

奇妙なことに、assertTrue(x.methodB(argument).equals( "good")); 大丈夫です

2番目のassertTrue(x.methodA(argument).equals( "good"));のみ OKではありません

実際、helper.methodA(argument)は「toto」を返します->模擬結果ではなく実際の結果

この場合、mockitoに「good」を返すように指示することはできません??? テストクラスがmethodBを呼び出した場合は問題ないようですが、スパイのメソッドがmethodBを呼び出した場合、それは機能しなくなります...

どうしたらよいかわかりません...同じクラスの2つのメソッドを単体テストし、テストを互いに独立させて、有名な模擬テストフレームワークがこの基本機能を実装しないようにするのは、とても奇妙なことです。 ?それは私たちが単に実際のユニットテストと呼んでいるものではありませんか?テストされたオブジェクトでスパイメソッドを使用しないように彼らが言う理由を理解していない...

ありがとう

4

2 に答える 2

4

更新: 以下の内容を書きましたが、しばらくして、部分的なスタブを効果的に実行できる .thenCallRealMethod() を発見しました。Mockito の作成者は、リファクタリングを使用して依存関係を異なるクラスに分離することを推奨しています。ただし、部分的にスタブする手段は提供します。このアプローチを実証するテスト メソッドを追加し、元のコメントを残します。

オリジナル: 私は Mockito が本当に好きですが、これは EasyMock が勝つ場所の 1 つです。Mockito を使用しない 2 つの解決策があります。1 つ目は、テスト インスタンスで methodB をオーバーライドすることです。もう 1 つは、EasyMock を使用して部分的にモックすることです。

import org.junit.Test;
import static org.junit.Assert.*;
import static org.easymock.EasyMock.*;

public class PartialMockTest {

    class ClassX {
        String methodA(String arg) {return methodB(arg);}
        String methodB(String arg) {return "toto";}
    }

    @Test
    public void MockitoOnClassX(){
        ClassX classx = mock(ClassX.class);
        when(classx.methodB("hiyas")).thenReturn("tomtom");
        when(classx.methodA(anyString())).thenCallRealMethod();
        String response = classx.methodA("hiyas");
        assertEquals("tomtom",response);
    }


    @Test
    public void OverrideOnClassX() {
        ClassX classx = new ClassX(){@Override String methodB(String arg){return "tomtom";}};
        String response = classx.methodA("hiyas");
        assertEquals("tomtom",response);
    }

    @Test
    public void PartialMockOnClassX() throws NoSuchMethodException {
        ClassX classx = createMockBuilder(ClassX.class).addMockedMethod("methodB").createMock();
        expect(classx.methodA("hiyas")).andReturn("tomtom");
        replay(classx);
        String response = classx.methodA("hiyas");
        assertEquals("tomtom",response);
    }

}
于 2011-01-03T20:39:17.440 に答える
2

スパイはスパイされるオブジェクトとは別のオブジェクトです。スパイは、スパイされたオブジェクトに委任するだけです。したがって、スパイされたオブジェクトが methodA から methodB を呼び出す場合、スパイではなく、それ自体で呼び出されます。

于 2010-11-22T14:08:50.280 に答える