Я разработал приложение для Android, которое использует модификацию с rxJava, и теперь я пытаюсь настроить модульные тесты с помощью Mockito, но я не знаю, как издеваться над ответами api, чтобы создать тесты, которые не делать реальные вызовы, но иметь поддельные ответы.
Например, я хочу проверить, что метод syncGenres отлично работает для моего SplashPresenter. Мои классы следующие:
public class SplashPresenterImpl implements SplashPresenter {
private SplashView splashView;
public SplashPresenterImpl(SplashView splashView) {
this.splashView = splashView;
}
@Override
public void syncGenres() {
Api.syncGenres(new Subscriber<List<Genre>>() {
@Override
public void onError(Throwable e) {
if(splashView != null) {
splashView.onError();
}
}
@Override
public void onNext(List<Genre> genres) {
SharedPreferencesUtils.setGenres(genres);
if(splashView != null) {
splashView.navigateToHome();
}
}
});
}
}
класс Api выглядит следующим образом:
public class Api {
...
public static Subscription syncGenres(Subscriber<List<Genre>> apiSubscriber) {
final Observable<List<Genre>> call = ApiClient.getService().syncGenres();
return call
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(apiSubscriber);
}
}
Теперь я пытаюсь проверить класс SplashPresenterImpl, но я не знаю, как это сделать, я должен сделать что-то вроде:
public class SplashPresenterImplTest {
@Mock
Api api;
@Mock
private SplashView splashView;
@Captor
private ArgumentCaptor<Callback<List<Genre>>> cb;
private SplashPresenterImpl splashPresenter;
@Before
public void setupSplashPresenterTest() {
// Mockito has a very convenient way to inject mocks by using the @Mock annotation. To
// inject the mocks in the test the initMocks method needs to be called.
MockitoAnnotations.initMocks(this);
// Get a reference to the class under test
splashPresenter = new SplashPresenterImpl(splashView);
}
@Test
public void syncGenres_success() {
Mockito.when(api.syncGenres(Mockito.any(ApiSubscriber.class))).thenReturn(); // I don't know how to do that
splashPresenter.syncGenres();
Mockito.verify(api).syncGenres(Mockito.any(ApiSubscriber.class)); // I don't know how to do that
}
}
Есть ли у вас какие-либо идеи о том, как мне высмеивать и проверять ответы api? Спасибо заранее!
EDIT: Следуя @invariant предложение, теперь я передаю клиентский объект моему ведущему, и что api возвращает Observable вместо подписки. Тем не менее, я получаю исключение NullPointerException у моего подписчика при выполнении вызова api. Класс тестирования выглядит следующим образом:
public class SplashPresenterImplTest {
@Mock
Api api;
@Mock
private SplashView splashView;
private SplashPresenterImpl splashPresenter;
@Before
public void setupSplashPresenterTest() {
// Mockito has a very convenient way to inject mocks by using the @Mock annotation. To
// inject the mocks in the test the initMocks method needs to be called.
MockitoAnnotations.initMocks(this);
// Get a reference to the class under test
splashPresenter = new SplashPresenterImpl(splashView, api);
}
@Test
public void syncGenres_success() {
Mockito.when(api.syncGenres()).thenReturn(Observable.just(Collections.<Genre>emptyList()));
splashPresenter.syncGenres();
Mockito.verify(splashView).navigateToHome();
}
}
Почему я получаю это исключение NullPointerException?
Спасибо большое!