我假设在使用模型 - 视图 - 演示者(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();
,但这无法通过我的测试。
答案 0 :(得分:4)
我不建议在演示者中使用Android类。这将允许您将演示者测试为本地单元测试(经典的Java单元测试)。
如果您仍想在演示者中使用Android类,请不要使用dagger对presenter依赖项进行属性注入。我要做的就是将它们传递给演示者的构造函数。
然后,模拟所有演示者的依赖关系并创建将要测试的Presenter。您正在嘲笑要测试的演示者。不要这样做,只需创建一个新的LoginPresenterImpl
并通过setUp方法中的构造函数将其所有依赖项传递给它来初始化它。
Here你有几个简单的演示者测试的例子。