我的测试中需要 Robolectric 和 Mockito,每个都提出自己的 TestRunner

I need both Robolectric and Mockito in my test, each one proposes their own 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 注释冲突,那我该怎么办?

使用 Robolectric 运行器。 Robolectric 使用自己的类加载器,有利于替换 Android API,所以它确实需要自己处理类加载。没有其他方法可以使用 Robolecric。

有几种初始化 Mockito 的方法(参见 this SO answer),它们严格等同于使用运行器,但对您的情况最有意义的两种是:

  • 使用 MockitoRule,因为您已经在使用 JUnit4:

    @Rule public MockitoRule rule = MockitoJUnit.rule();
    
  • 创建手动 @Before@After 方法:

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