web-dev-qa-db-ja.com

テストにはRobolectricとMockitoの両方が必要です。それぞれが独自のTestRunnerを提案します。

テストにはRobolectricとMockitoの両方が必要です。それぞれが独自のTestRunnerを提案しますが、どうすればよいですか?

私はこのコードを持っています:

_@RunWith(MockitoJUnitRunner.class)
@EBean
public class LoginPresenterTest {

    @Bean
    LoginPresenter loginPresenter;

    @Mock
    private LoginView loginView;

    @AfterInject
    void initLoginPresenter() {
        loginPresenter.setLoginView(loginView);
    }

    @Test
    public void whenUserNameIsEmptyShowErrorOnLoginClicked() throws Exception {
        when(loginView.getUserName()).thenReturn("");
        when(loginView.getPassword()).thenReturn("asdasd");
        loginPresenter.onLoginClicked();
        verify(loginView).setEmailFieldErrorMessage();
    }
}
_

問題は、AndroidAnnotationsが依存関係を注入せず、LoginPresenterを使おうとするとNPEが発生することです。

誰かが私に_LoginPresenter__コンストラクターを使用するように言ったので、次のように自分で依存関係を強制的に注入できます。

_LoginPresenter loginPresenter = LoginPresenter_.getInstance_(context);
_

コンテキストにアクセスするには、ユニットテストからAndroidインストルメンテーションテストを実行してgetInstrumentation().getTargetContext()を実行する必要がありましたが、インストルメンテーションテストではなくユニットテストが必要です。

そのため、別の人が私にRobolectricを使用するように言いました-それは私にアプリケーションコンテキストを提供できるはずです。

ただし、Robolectricの開始ページを見ると、

_@RunWith(RobolectricGradleTestRunner.class)
_

これは、Mockitoの現在の_@RunWith_アノテーションと衝突するので、どうすればよいですか?

19
J. K.

Robolectricランナーを使用します。Robolectricは、Android APIの代わりに使用する独自のクラスローダーを使用するため、実際に使用します。クラスローディングを独自に処理する必要があります。Robolexricを使用する他の方法はありません。

Mockitoを初期化する方法はいくつかあります( this SO answer を参照)。これは、ランナーを使用するのと厳密に同等ですが、この2つがあなたのケースに最も適しています。は:

  • MockitoRule を使用します。これは、すでにJUnit4を使用しているためです。

    @Rule public MockitoRule rule = MockitoJUnit.rule();
    
  • マニュアルの作成@Beforeおよび@Afterメソッド:

    @Before public void setUpMockito() {
      MockitoAnnotations.initMocks(this);
    }
    
    @After public void tearDownMockito() {
      Mockito.validateMockitoUsage();
    }
    
30
Jeff Bowman