249

そのため、クラスレベルで静的変数としてモックオブジェクトを作成しています...あるテストでFoo.someMethod()は特定の値を返し、別のテストでは別の値を返したいと考えています。私が抱えている問題は、これを正しく機能させるためにモックを再構築する必要があるようだということです。モックの再構築を避け、各テストで同じオブジェクトを使用したいと思います。

class TestClass {

    private static Foo mockFoo;

    @BeforeClass
    public static void setUp() {
        mockFoo = mock(Foo.class);
    }

    @Test
    public void test1() {
        when(mockFoo.someMethod()).thenReturn(0);

        TestObject testObj = new TestObject(mockFoo);

        testObj.bar(); // calls mockFoo.someMethod(), receiving 0 as the value

    }

    @Test
    public void test2() {
        when(mockFoo.someMethod()).thenReturn(1);

        TestObject testObj = new TestObject(mockFoo);

        testObj.bar(); // calls mockFoo.someMethod(), STILL receiving 0 as the value, instead of expected 1.

    }

}

2番目のテストでは、testObj.bar()が呼び出されたときに値として0を受け取っています...これを解決するための最良の方法は何ですか?各テストで異なるモックを使用できることはわかっていFooますが、複数のリクエストをからチェーンするmockFoo必要があります。つまり、各テストでチェーンを実行する必要があります。

4

5 に答える 5

498

連続呼び出しをスタブすることもできます(2.8.9 APIの#10)。この場合、複数のthenReturn呼び出し、または複数のパラメーター(varargs)を持つ1つのthenReturn呼び出しを使用します。

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;

public class TestClass {

    private Foo mockFoo;

    @Before
    public void setup() {
        setupFoo();
    }

    @Test
    public void testFoo() {
        TestObject testObj = new TestObject(mockFoo);

        assertEquals(0, testObj.bar());
        assertEquals(1, testObj.bar());
        assertEquals(-1, testObj.bar());
        assertEquals(-1, testObj.bar());
    }

    private void setupFoo() {
        mockFoo = mock(Foo.class);

        when(mockFoo.someMethod())
            .thenReturn(0)
            .thenReturn(1)
            .thenReturn(-1); //any subsequent call will return -1

        // Or a bit shorter with varargs:
        when(mockFoo.someMethod())
            .thenReturn(0, 1, -1); //any subsequent call will return -1
    }
}
于 2011-05-19T21:32:59.973 に答える
56

何かを返すために検索し、次に別の呼び出しを検索するすべての人は、例外をスローします。

when(mockFoo.someMethod())
        .thenReturn(obj1)
        .thenReturn(obj2)
        .thenThrow(new RuntimeException("Fail"));

また

when(mockFoo.someMethod())
        .thenReturn(obj1, obj2)
        .thenThrow(new RuntimeException("Fail"));
于 2018-05-24T12:09:04.730 に答える
48

まず第一に、モックを静的にしないでください。プライベートフィールドにします。@BeforesetUpクラスをnotに入れるだけ@BeforeClassです。それはたくさん実行されるかもしれませんが、それは安いです。

第二に、あなたが今それを持っている方法は、テストに応じて異なるものを返すためにモックを取得する正しい方法です。

于 2010-11-18T15:45:52.697 に答える
36

または、さらにクリーン:

when(mockFoo.someMethod()).thenReturn(obj1, obj2);
于 2018-10-24T11:23:46.303 に答える
24

when()メソッドの代わりにspy()とdoReturn()を使用している人の場合:

さまざまな呼び出しでさまざまなオブジェクトを返す必要があるのは、次のとおりです。

doReturn(obj1).doReturn(obj2).when(this.spyFoo).someMethod();

古典的なモックの場合:

when(this.mockFoo.someMethod()).thenReturn(obj1, obj2);

またはスローされる例外を除いて:

when(mockFoo.someMethod())
        .thenReturn(obj1)
        .thenThrow(new IllegalArgumentException())
        .thenReturn(obj2, obj3);
于 2018-03-07T16:41:43.033 に答える