我正在学习 Android MVP 架构并尝试使用 Mockito/JUnit 测试一些方法。我从本教程中学习:
https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex
我在我的 Android MVP 架构类型应用程序中测试 Presenter 方法时遇到问题。
这是我的 Presenter 类:
public class ForgotPasswordPresenter implements ForgotPasswordMVP.Presenter{
private ForgotPasswordMVP.View view;
private ForgotPasswordMVP.Model model;
public ForgotPasswordPresenter(FirebaseAuthService firebaseAuthService, ForgotPasswordMVP.Model model) {
this.model = model;
}
@Override
public void setView(ForgotPasswordMVP.View view) {
this.view = view;
}
@Override
public void sendButtonClicked() {
if(view != null) {
view.showProgressBar();
model.sendEmail(view.getEmail(), new
ForgotPasswordMVP.Model.SendForgotEmailCallback() {
@Override
public void onEmailSent(boolean sent) {
if(sent) {
view.hideProgressBar();
view.showEmailSent();
}
else{
//show some error on UI
}
}
});
}
}
}
这是 MVP.Model 结构的契约接口。我定义了自定义回调:
interface Model{
interface SendForgotEmailCallback {
void onEmailSent(boolean sent);
}
void sendEmail(String email, @NonNull SendForgotEmailCallback SendForgotEmailCallback) ;
}
在我的模型中,我做这样的事情,我只是使用 Firebase 来重置密码:
public class ForgotPasswordModel implements ForgotPasswordMVP.Model{
private FirebaseAuthService firebaseAuthService;
public ForgotPasswordModel(FirebaseAuthService firebaseAuthService) {
this.firebaseAuthService = firebaseAuthService;
}
@Override
public void sendEmail(String email, @NonNull final SendForgotEmailCallback SendForgotEmailCallback) {
firebaseAuthService.sendPasswordResetEmail(email).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
SendForgotEmailCallback.onEmailSent(true);
}
else{
SendForgotEmailCallback.onEmailSent(false);
}
}
});
}
}
现在,我想测试负责发送电子邮件的方法,只需单击发送按钮。这是我的测试原型:
public class ForgotPasswordPresenterTest {
@Mock
ForgotPasswordMVP.Model model;
@Mock
ForgotPasswordMVP.View view;
@Mock
FirebaseAuthService firebaseAuthService;
@Captor
private ArgumentCaptor<ForgotPasswordMVP.Model.SendForgotEmailCallback> sendForgotEmailCallbackArgumentCaptor;
private ForgotPasswordPresenter forgotPasswordPresenter;
@Before
public void setupForgotPasswordPresenter(){
MockitoAnnotations.initMocks(this);
forgotPasswordPresenter = new ForgotPasswordPresenter(firebaseAuthService, model);
forgotPasswordPresenter.setView(view);
}
@Test
public void sendButtonClicked_shouldShowEmailSent(){
when(view.getEmail()).thenReturn("[email protected]");
forgotPasswordPresenter.sendButtonClicked();
verify(model).sendEmail(view.getEmail(), sendForgotEmailCallbackArgumentCaptor.capture());
sendForgotEmailCallbackArgumentCaptor.getValue().onEmailSent(true);
verify(view).showEmailSent();
}
}
因此,当涉及到 verify(model).sendEmail ... 时,它崩溃了,并且出现了 Mockito 的这个异常:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:参数匹配器的使用无效!预期 2 个匹配器,记录 1 个:-> 在 com.example.app.ui.login.ForgotPasswordPresenterTest.sendButtonClicked_shouldShowEmailSent(ForgotPasswordPresenterTest.java:53) 如果匹配器与原始值组合,则可能发生此异常://不正确: ), "原始字符串"); 使用匹配器时,所有参数都必须由匹配器提供。例如: //correct: someMethod(anyObject(), eq("String by matcher"));
有关更多信息,请参阅 Matchers 类的 javadoc。
谁能帮我这个?我是初学者,想弄清楚,但现在真的没有线索。
由于您正在使用capture()
(被视为匹配器)捕获参数,因此您必须eq
将verify
. 在您的测试中view.getEmail()
返回原始值(“[email protected]”),因此您的验证将更改为:
verify(model).sendEmail(eq(view.getEmail()), sendForgotEmailCallbackArgumentCaptor.capture());
请注意,您现在view.getEmail()
将使用eq
.
需要记住的一件好事是:如果您对任何方法参数使用匹配器,则应使用匹配器验证所有参数(eq
用于原始值)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句