У меня есть интерфейс API, и я тестирую View
, который включает в себя сетевые вызовы.
@Config(emulateSdk = 18)
public class SampleViewTest extends RobolectricTestBase {
ServiceApi apiMock;
@Inject
SampleView fixture;
@Override
public void setUp() {
super.setUp(); //injection is performed in super
apiMock = mock(ServiceApi.class);
fixture = new SampleView(activity);
fixture.setApi(apiMock);
}
@Test
public void testSampleViewCallback() {
when(apiMock.requestA()).thenReturn(Observable.from(new ResponseA());
when(apiMock.requestB()).thenReturn(Observable.from(new ResponseB());
AtomicReference<Object> testResult = new AtomicReference<>();
fixture.updateView(new Callback() {
@Override
public void onSuccess(Object result) {
testResult.set(result);
}
@Override
public void onError(Throwable error) {
throw new RuntimeException(error);
}
});
verify(apiMock, times(1)).requestA();
verify(apiMock, times(1)).requestB();
assertNotNull(testResult.get());
}
}
По какой-то причине методы apiMock
никогда не вызываются и проверка всегда терпит неудачу.
На мой взгляд, я называю свой api таким образом
apiV2.requestA()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer());
Что мне здесь не хватает?
Обновление # 1:
После некоторого расследования выясняется, что когда в моей реализации (пример выше) я observeOn(AndroidSchedulers.mainThread())
абонент не вызывается. Все еще не знаю почему.
Обновление # 2:
При подписке точно так же apiV2.requestA().subscribe(new Observer());
все работает просто отлично - mock api вызывается и проходит тест.
Продвижение ShadowLooper.idleMainLooper(5000)
ничего не делало. Даже захваченный петлитель от обработчика в HandlerThreadScheduler
и продвинул его. Тот же результат.
Обновление # 3: Добавление фактического кода, в котором используется API.
public void updateView(final Callback) {
Observable.zip(wrapObservable(api.requestA()), wrapObservable(api.requestB()),
new Func2<ResponseA, ResponseB, Object>() {
@Override
public Object call(ResponseA responseA, ResponseB responseB) {
return mergeBothResponses(responseA, responseB);
}
}
).subscribe(new EndlessObserver<Object>() {
@Override
public void onError(Throwable e) {
Log.e(e);
listener.onError(e);
}
@Override
public void onNext(Object config) {
Log.d("Configuration updated [%s]", config.toString());
listener.onSuccess(config);
}
});
}
protected <T> Observable<T> wrapObservable(Observable<T> observable) {
return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}