Reputation: 2066
I am new to Unit Testing in mvp, I want to make a verrry basic test to the presenter, which is responsible for making login, I just want to assert on
view.onLoginSuccess();
Here is the PresenterCode:
public LoginPresenter(LoginViewContract loginView,
LoginModelContract loginModel,
CurrentUserLoginModelContract currentUserLoginModel,
CompositeDisposable subscriptions) {
this.subscriptions = subscriptions;
this.loginView = loginView;
this.loginModel = loginModel;
this.currentUserLoginModel = currentUserLoginModel;
}
@Override
public void loginPres(LoginRequest loginRequest) {
loginModel.loginUser(loginRequest)
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<LoginResponse>() {
@Override
public void onSubscribe(Disposable d) {
subscriptions.add(d);
}
@Override
public void onSuccess(LoginResponse loginResponse) {
// do something with the response
loginView.loginSuccessMessage(token, true);
}
@Override
public void onError(Throwable e) {
loginView.loginFailedErrorMessage();
Timber.e(e, "Error while trying to login");
}
});
}
Android here is the test code:
@RunWith(MockitoJUnitRunner.class)
public class LoginPresenterTest {
@Mock
LoginViewContract view;
@Mock
LoginModelContract model;
@Mock
CurrentUserLoginModelContract localModel;
LoginPresenter SUT;
@Before
public void setUp() throws Exception {
compositeDisposable = new CompositeDisposable();
SUT = new LoginPresenter(view, model, localModel, compositeDisposable);
}
@Test
public void name() {
LoginResponse singleResponse = new LoginResponse();
TestScheduler testScheduler = new TestScheduler();
when(model.loginUser(any()))
.thenReturn(Single.just(new LoginResponse()));
SUT.loginPres(any());
}
It just gives me NullPointerException, I think that Knowing how to test the success will help me test everything else, I have read about the TestScheduler, I tried it but did not help, I think I am doing something wrong, thanks in advance.
Upvotes: 3
Views: 862
Reputation: 8190
The problem is your TestScheduler
. You should create a helper class to provide schedulers
for your observable
. Something likes:
class RxProvider{
fun provideIOScheduler()
fun provideAndroidMainScheduler()
}
//Then you can call the rxprovider inside your presenter:
loginModel.loginUser(loginRequest)
.subscribeOn(rxProvider.provideIOScheduler())
.observeOn(rxProvider.provideAndroidMainScheduler())
// inside your test cases
when(rxProvider....).thenReturn(testSchedulers)
P/s: 1 more tip, you should mock your LoginResponse
instead of calling new
everywhere.
Upvotes: 1
Reputation: 4361
You made a TestScheduler in your test class, but your Presenter doesn't know about it. Just like you have your view, model, localModel, and compositeDisposable as dependencies of the presenter, you need to add two new dependencies: Your IO Scheduler (Schedulers.computation()
in the non test code, and new TestScheduler()
in the test code) and your UI Scheduler (AndroidSchedulers.mainThread()
in the non test code, and new TestScheduler()
in the test code).
Once you do that, you can set up 2 new TestSchedulers in your test code. Declare them as testIoScheduler = new TestScheduler()
and testUiScheduler = new TestScheduler()
. Then, right after you call the method under test (SUT.loginPres(any());
), you can invoke the schedulers with testIoScheduler.triggerActions()
and testUiScheduler.triggerActions()
Upvotes: 1