モデルビューアプレゼンター(MVP)パターンを使用すると、単体テストのテストがずっと簡単になると想定されていましたが、始まりも早く進む依存関係を追加して、Roboelectric
とMockito
という単体テストを書いて、プレゼンターで使用されているすべての依存関係をモックにしました。プレゼンターレイヤーに適切なアンドロイドユニットテストを書く方法
public class LoginPresenterImpl implements ILoginPresenter {
@Inject
Bus bus;
@Inject
ISharedPreferencesRepository mSharedPreferencesRepository;
private final String LOG_TAG = "LOGIN_PRESENTER";
private ILoginView loginView;
private LoginInteractorImpl loginInteractor;
private long mLastClickTime = 0;
public LoginPresenterImpl() {
MyApplication.getObjectGraph().inject(this);
this.loginInteractor = new LoginInteractorImpl();
}
@Override
public void setLoginView(ILoginView loginView) {
this.loginView = loginView;
if(mSharedPreferencesRepository.isLoggedIn()) {
Log.i(LOG_TAG, "User logged in already");
this.loginView.navigateToHome();
}
}
@Override
public void validateCredentials(String username, String password) {
if(SystemClock.elapsedRealtime() - mLastClickTime < 1000)
return;
mLastClickTime = SystemClock.elapsedRealtime();
if(username.equals("") || username == null) {
loginView.setUsernameError();
return;
} else if(password.equals("") || password == null){
loginView.setPasswordError();
return;
}
loginView.showProgress();
loginInteractor.login(username, password, this);
}
@Override
public void onUsernameError() {
loginView.setUsernameError();
loginView.hideProgress();
}
@Override
public void onPasswordError() {
loginView.setPasswordError();
loginView.hideProgress();
}
@Subscribe
@Override
public void onSuccess(LoginEvent event) {
if (event.getIsSuccess()) {
mSharedPreferencesRepository.setLogin(true);
mSharedPreferencesRepository.setFirstTime(true);
mSharedPreferencesRepository.setUserId(event.getUserId());
loginView.navigateToHome();
loginView.hideProgress();
}
}
(試行):いくつかの参考のため
は、ここでは、ログインのための私のプレゼンターの一例であるまず私が間違っている場合は、しかし、で、私を修正テストケースの作成を開始するには、いくつかのオブジェクトをモックする必要があります: Bus
、ISharedPreferencesRepository
、ILoginView
、LoginInteractorImpl
。
私はこのようなものになってしまった:私は取るべき次のステップで失わ少しだ
@RunWith(MockitoJUnitRunner.class)
public class LoginPresenterImplTest {
@Mock
private ILoginView view;
@Mock
private LoginInteractorImpl interactor;
@Mock
private LoginPresenterImpl presenter;
@Before
public void setUp(){
}
@Test
public void shouldShowErrorMessageWhenUsernameIsEmpty() throws Exception {
when(view.getUsername()).thenReturn("");
when(view.getPassword()).thenReturn("test");
presenter.validateCredentials(view.getUsername(), view.getPassword());
}
}
。私は方法loiginView.setOnUsernameError()
verify(view, times(1)).setUsernameError();
を追加してこのシナリオで呼び出されることを確認しようとしていますが、これは私のテストに失敗します。
本当に 'validateCredentials'が呼び出されていますか?司会者は偽物のようです。 実際の呼び出しの前に 'when(presenter.validateCredentials(any()、any())。thenCallRealMethod();'を入れてみてください。 – ncphillips
@ncphillips 'validateCredentials()'がvoidを返すので、 : これは私に 'org.mockito.exceptions.misusing.UnfinishedStubbingException:'を投げました。 –