2017-07-18 21 views
0

我正在學習Android MVP體系結構並嘗試使用Mockito/JUnit測試某些方法。我是從本教程學習:Mockito InvalidUseOfMatchersException,嘗試使用自定義回調作爲參數的單元測試方法

https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex

我有在我的Android MVP架構類型的應用程序測試的演示方法的問題。

這裏是我的演示類:

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) ; 
} 

在我的模型我做這樣的東西,我只是用火力地堡重置密碼:

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(); 

} 

}

所以,當談到驗證(模型).sendEmail ...崩潰,並從該的Mockito例外出現:

組織.mockito.exceptions.misusing.InvalidUseOfMatchersException: 參數匹配器的使用無效! 2匹配器預期的,1記載: - >在com.example.app.ui.login.ForgotPasswordPresenterTest.sendButtonClicked_shouldShowEmailSent(ForgotPasswordPresenterTest.java:53) 可能會發生此異常,如果匹配器與原始值組合: //不正確的: someMethod(anyObject(),「raw String」); 使用匹配器時,所有參數必須由匹配器提供。 例如: //正確: someMethod(anyObject(),eq(「String by matcher」));

欲瞭解更多信息,請參閱Matcher類的javadoc。

任何人都可以幫助我嗎?我是初學者,試圖弄清楚,但現在真的沒有線索。

回答

1

由於您使用capture()(將其視爲匹配程序)捕獲參數,因此您必須對verify中的所有其他原始值使用eq。在您的測試view.getEmail()回到原始值(「[email protected]」),讓您的驗證就改成這樣:

verify(model).sendEmail(eq(view.getEmail()), sendForgotEmailCallbackArgumentCaptor.capture()); 

請注意,您現在將驗證view.getEmail()包裹着eq

要記住的一件好事是:如果您對任何方法參數使用匹配器,則應使用匹配器驗證所有參數(對於原始值使用eq)。

+0

感謝它的工作!我只能在9分鐘後接受你的回答,謝謝 – Konrad

+0

我現在有同樣的問題,當我有2個參數。 https://gist.github.com/oksett/78b76637257851d326ac8f8f5b93b201你能幫我嗎? – Konrad

+0

無論您有多少參數,它都應該像以前一樣工作。 – Abubakkar

相關問題