15

私はmockitoで問題に遭遇しました。私はWebアプリケーションを開発しています。私のテストでは、ユーザー管理は嘲笑されています。getLoggedInUser()メソッドによって返される User を変更しなければならない場合があります。

問題は、私のgetLoggedInUser()メソッドも . をスローできることAuthenticationExceptionです。

したがって、ユーザーなしから一部のユーザーに切り替えようとすると、への呼び出し

when(userProvider.getLoggedInUser()).thenReturn(user);

userProvider.getLoggedInUser()すでにスタブ化されているため、例外をスローしますthenTrow()

when例外を気にしないようにメソッドに指示する方法はありますか?

前もって感謝します - István

4

3 に答える 3

21

新しいMockitoバージョンでは、連続した呼び出しをスタブ化して、最初の缶で例外をスローし、2番目の呼び出しで値を返すことができます。

when(mock.someMethod("some arg"))
    .thenThrow(new RuntimeException())
    .thenReturn("foo");

https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#10

于 2012-06-14T08:39:10.203 に答える
5

あなたの質問に対する私の最初の反応は、あなたが1つのテストでやりすぎているように聞こえるということです。

テストを容易にし、単純にするために、各テストは1つのことだけをテストする必要があります。これは、単一責任の原則と同じです。プログラマーが1つのテストで複数のことをテストしようとしていて、それが原因であらゆる種類の問題を抱えていることがよくあります。したがって、各単体テストメソッドは次のフローに従う必要があります。

  1. テスト用に単一のシナリオを設定します。
  2. テスト対象のクラスを呼び出して、テスト対象のコードをトリガーします。
  3. 動作を確認します。

したがって、あなたの場合、少なくとも2つのテストが表示されると思います。1つはgetLoggedInUser()ユーザーを返し、もう1つはgetLoggedInUser()例外をスローします。そうすれば、モックでさまざまな動作をシミュレートしようとしても問題は発生しません。

頭に浮かぶのはスタブではないという2番目の考え。一連の期待値を設定できるため、代わりに期待値の使用を検討してください。つまり、最初の呼び出しはユーザーを返し、2番目の呼び出しは例外をスローし、3番目の呼び出しは別のユーザーを返します。

于 2010-11-14T23:30:06.667 に答える
5

when メソッドに例外を気にしないように指示する方法はありますか?

この質問に実際に答えるには:

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;

import org.junit.Test;
import org.mockito.Mockito;

import java.util.ArrayList;

public class MyTest {

    @Test
    public void testA() {

        // setup
        ArrayList<Object> list = mock(ObjectArrayList.class);
        when(list.indexOf(any())).thenReturn(6);
        when(list.indexOf(any())).thenReturn(12);

        // execute
        int index = list.indexOf(new Object());

        // verify
        assertThat(index, is(equalTo(12)));
    }

    @Test
    public void testB() {

        // setup
        ArrayList<Object> list = mock(ObjectArrayList.class);
        when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!"));
        when(list.add(any())).thenReturn(true);

        // execute
        list.add(new Object());
    }

    @Test
    public void testC() {

        // setup
        ArrayList<Object> list = mock(ObjectArrayList.class);
        when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!"));
        Mockito.reset(list);
        when(list.add(any())).thenReturn(true);

        // execute
        list.add(new Object());
    }

    /**
     * Exists to work around the fact that mocking an ArrayList<Object>
     * requires a cast, which causes "unchecked" warnings, that can only be suppressed...
     */
    class ObjectArrayList extends ArrayList<Object> {

    }
}

TestB取り除くことができないというアサートのために失敗します。メソッドを使用してモックをリセットし、そのコマンドを削除する方法をTestC示します。resetthenThrow

私が持っているいくつかのより複雑な例では、リセットが常に機能するとは限らないことに注意してください。PowerMockito.mockではなくMockito.mock?を使用しているためだと思われます。

于 2017-05-11T13:36:29.927 に答える