我有登录演示者类,并且想要对其进行单元测试。
这就是登录演示者类的样子:
public class LoginPresenter<V extends LoginMvpView> extends BasePresenter<V>
implements LoginMvpPresenter<V> {
@Inject
public LoginPresenter(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
}
@Override
public void onAttach(V mvpView) {
super.onAttach(mvpView);
}
@Override
public void login(String email, String password) {
getMvpView().hideKeyboard();
LoginRequest request = new LoginRequest();
request.setEmail(email);
request.setPassword(password);
if(email == null || email.length() == 0){
getMvpView().onError(R.string.msg_pls_fill_email);
return;
}
if(password == null || password.length() == 0){
getMvpView().onError(R.string.msg_pls_fill_password);
return;
}
getMvpView().showLoading();
getCompositeDisposable().add(getDataManager()
.login(request)
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(response -> {
if (!isViewAttached()) {
return;
}
getMvpView().openMainActivity();
}, throwable -> {
if (!isViewAttached()) {
return;
}
getMvpView().hideLoading();
getMvpView().onError(R.string.api_default_error);
})
);
}
}
这是测试类:
@RunWith(MockitoJUnitRunner.class)
public class LoginPresenterTest {
@Mock
LoginMvpView mMockLoginMvpView;
@Mock
DataManager mMockDataManager;
private LoginPresenter<LoginMvpView> mLoginPresenter;
private TestScheduler mTestScheduler;
@BeforeClass
public static void onlyOnce() throws Exception {
}
@Before
public void setUp() throws Exception {
CompositeDisposable compositeDisposable = new CompositeDisposable();
mTestScheduler = new TestScheduler();
TestSchedulerProvider testSchedulerProvider = new TestSchedulerProvider(mTestScheduler);
mLoginPresenter = new LoginPresenter<>(
mMockDataManager,
testSchedulerProvider,
compositeDisposable);
mLoginPresenter.onAttach(mMockLoginMvpView);
}
@Test
public void testServerLoginSuccess() {
String email = "dummy@gmail.com";
String password = "password";
LoginResponse loginResponse = new LoginResponse();
doReturn(Single.just(loginResponse))
.when(mMockDataManager)
.login(new LoginRequest(email, password));
mLoginPresenter.login(email, password);
mTestScheduler.triggerActions();
verify(mMockLoginMvpView).showLoading();
verify(mMockLoginMvpView).hideLoading();
verify(mMockLoginMvpView).openMainActivity();
}
@After
public void tearDown() throws Exception {
mLoginPresenter.onDetach();
}
}
这是调度程序提供程序类:
public class TestSchedulerProvider implements SchedulerProvider {
private final Scheduler mTestScheduler;
public TestSchedulerProvider(Scheduler testScheduler) {
this.mTestScheduler = testScheduler;
}
@Override
public Scheduler ui() {
return mTestScheduler;
}
@Override
public Scheduler computation() {
return mTestScheduler;
}
@Override
public Scheduler io() {
return mTestScheduler;
}
}
运行测试时出现此错误:
java.lang.NullPointerException
at com.logab.customerui.login.LoginPresenter.login(LoginPresenter.java:85)
at com.logab.customer.ui.login.LoginPresenterTest.testServerLoginSuccess(LoginPresenterTest.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
....
....
...
[MockitoHint] LoginPresenterTest.testServerLoginSuccess (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.logap.customer.ui.login.LoginPresenterTest.testServerLoginSuccess(LoginPresenterTest.java:60)
[MockitoHint] ...args ok? -> at com.logap.customer.ui.login.LoginPresenter.login(LoginPresenter.java:84)
处理该错误将转到此行:
.subscribeOn(getSchedulerProvider().io())
注意:我正在使用dagger2提供依赖项。
任何人都可以帮忙吗?谢谢。
答案 0 :(得分:1)
您的代码为此行抛出NullPointerException
getDataManager().login(request)
.subscribeOn(getSchedulerProvider().io())
因为它与您的登录方法调用的参数不匹配。
您必须调整测试,例如:
(使用ArgumentMatcher
的{{1}})
eq
使用匹配器(假设LoginRequest对象的doReturn(Single.just(loginResponse))
.when(mMockDataManager)
.login(eq(new LoginRequest(email, password)));
和equals
已正确实现)应该可以解决您的问题。
或者,如果您不需要参数完全匹配,
您也可以改用hashcode
。