已解决:即使Argument Captor上的getValue()向您显示了此信息,也是正常的。老实说,我期望在此处的OnLoginWithEmailCallback接口上看到实例。我这方面的问题与在mView上生成NPE的方法调用有关。现在就像魅力一样。
原始问题:
我正在MVP应用程序中使用Mockito来实现我的第一个单元测试,并且我需要在用户登录时模拟回调的行为。我正在使用Firebase处理身份验证。
我从这里遵循了一个很好的教程:https://fernandocejas.com/2014/04/08/unit-testing-asynchronous-methods-with-mockito/。
我正在测试中的类上调用方法。此方法在Auth Presenter上调用另一个方法,该方法可以完成实际工作
mPresenter.performLoginWithEmail(EMAIL, PASSWORD);
然后,我正在验证Auth Presenter类中的下划线方法是否已被调用。我尝试捕获回调接口。
verify(mAuthPresenter, times(1)).login(mOnLoginWithEmailCallbackArgumentCaptor.capture(),
eq(EMAIL), eq(PASSWORD));
问题是Argument Captor的getValue()返回了mPresenter(正在测试的类)的实例,而不是OnLoginWithEmailCallback接口类。因此,我得到了NPE。
mOnLoginWithEmailCallbackArgumentCaptor.getValue().onLoginWithEmailSuccess();
这是完整的测试课程:
@RunWith(MockitoJUnitRunner.class)
public class LoginPresenterTest {
private static String EMAIL = "test@rmail.com";
private static String PASSWORD = "1234";
//class under test
private LoginPresenter mPresenter;
@Mock
AuthPresenter mAuthPresenter;
@Captor
private ArgumentCaptor<OnLoginWithEmailCallback> mOnLoginWithEmailCallbackArgumentCaptor;
@Mock
ILoginActivityView mView;
@Before
public void setupLoginPresenter() {
MockitoAnnotations.initMocks(this);
// Get a reference to the class under test
mPresenter = new LoginPresenter(mView, mAuthPresenter);
}
@Test
public void performLoginWithEmail() {
mPresenter.performLoginWithEmail(EMAIL, PASSWORD);
//wanting to have control over the callback object. therefore call capture to then call methods on the interface
verify(mAuthPresenter, times(1)).login(mOnLoginWithEmailCallbackArgumentCaptor.capture(),
eq(EMAIL), eq(PASSWORD));
mOnLoginWithEmailCallbackArgumentCaptor.getValue().onLoginWithEmailSuccess();
InOrder inOrder = Mockito.inOrder(mView);
inOrder.verify(mView).goToMap();
inOrder.verify(mView).hideProgressBar();
}
}
编辑:这是对 mAuthPresenter.login 的调用:
已解决:getLoginActivityView()导致发生NPE
public void performLoginWithEmail(String email, String password) {
mAuthPresenter.login(new OnLoginWithEmailCallback() {
@Override
public void onLoginWithEmailSuccess() {
getLoginActivityView().goToMap();
getLoginActivityView().hideProgressBar();
}
@Override
public void onLoginWithEmailFailed(String error) {
getLoginActivityView().hideProgressBar();
getLoginActivityView().showToast(error);
}
}, email, password);
}
我还尝试使用Mockito中的doAnswer:
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
((OnLoginWithEmailCallback)invocation.getArguments()[0]).onLoginWithEmailSuccess();
return null;
}
}).when(mAuthPresenter).login(
any(OnLoginWithEmailCallback.class, EMAIL, PASSWORD));
仍然,invocation.getArguments()返回被测类的一个实例(LoginPresenter),因此问题与以前相同。你能帮我吗?
答案 0 :(得分:0)
问题是我被Argument Captor弄糊涂了,这使我返回了调用者类的实例(LoginPresenter)。在我的情况下,问题在于匿名类OnLoginWithEmailCallback()中的方法正在抛出NPE。