Issue
I have login presenter class and want to make unit test on it.
So this is how login presenter class looks like:
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);
})
);
}
}
And this is the test class:
@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 = "[email protected]";
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();
}
}
And this is scheduler provider class:
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;
}
}
I got this error when run the test:
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)
Tracing that error will go to this line:
.subscribeOn(getSchedulerProvider().io())
Note: I'm using dagger2 to provide dependencies.
Anyone can help? Thanks.
Solution
Your code throws a NullPointerException for this line
getDataManager().login(request)
.subscribeOn(getSchedulerProvider().io())
because it could not match the parameter of your login method call.
You have to adjust your test, for example:
(using ArgumentMatcher's eq)
doReturn(Single.just(loginResponse))
.when(mMockDataManager)
.login(eq(new LoginRequest(email, password)));
Using the matcher (assuming the equals and hashcode of the LoginRequest object are implemented correctly) should solve your issue.
Alternatively, if you do not require an exact match for the parameters,
you could also use any(LoginRequest.class) instead.
Answered By - second
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.