我正在使用Retrofit测试真实的API调用,如下所示:
@Test
public void getList(){
TestObserver<MyResponse> testObserver = api
.getResults(params)
.lift(apiErrorOperator)
.lift(emptyResponseOperator)
.test();
testObserver.awaitTerminalEvent();
testObserver.assertError(ApiException.class);
}
测试失败,出现以下两个错误:
Caused by: java.lang.IllegalStateException: onSubscribe not called in proper order
和
Caused by: com.example.myapplication.repository.ApiException: Search found 0 results
第二个很有意义,因为这是我所期望的行为。但是,我不明白为什么testObserver.assertError(ApiException.class)
不能返回true,为什么我也遇到第一个错误。
对于第一个错误,此行java.lang.IllegalStateException: onSubscribe not called in proper order
从observer.onError(new ApiException("Search found 0 results"))
的行emptyResponseOperator
处抛出。以下是完整课程的代码:
public class EmptyResponseOperator implements ObservableOperator<MyResponse, MyResponse> {
@Override
public Observer<? super MyResponse> apply(Observer<? super MyResponse> observer) throws Exception {
return new DisposableObserver<MyResponse>() {
@Override
public void onNext(MyResponse myResponse) {
if(myResponse.getTotalResultsCount() == 0)
observer.onError(new ApiException("Search found 0 results"));
else{
observer.onNext(myResponse);
observer.onComplete();
}
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onComplete() {
observer.onComplete();
}
};
}
}
这也是ApiErrorOperator类的代码:
public class ApiErrorOperator<T> implements ObservableOperator<T, Response<T>> {
@Override
public Observer<? super Response<T>> apply(Observer<? super T> observer) throws Exception {
return new DisposableObserver<Response<T>>() {
@Override
public void onNext(Response<T> tResponse) {
if(!tResponse.isSuccessful()){
try {
if (tResponse.errorBody() != null) {
observer.onError(new ApiException(tResponse.errorBody().string()));
}else{
observer.onError(new ApiException(C.ERROR_UNKNOWN));
}
} catch (IOException e) {
observer.onError(new ApiException(C.ERROR_IO));
}
}
else if (tResponse.body() == null) {
observer.onError(new ApiException(C.ERROR_NOT_FOUND));
}else{
observer.onNext(tResponse.body());
observer.onComplete();
}
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onComplete() {
observer.onComplete();
}
};
}
}
答案 0 :(得分:1)
您的实现是错误的,请尝试避免代码中的链向下游传播。
检查以下示例并在此处浏览文档。
Single.just(1)
.delaySubscription(Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter e) throws Exception {
if (!e.isDisposed()) {
e.onError(new TestException());
}
}
}))
.test()
.assertFailure(TestException.class);
-onSubscribe
将它们连接起来就可以了。
另一种解决方案
创建自定义运算符。 How?
答案 1 :(得分:1)
我们不建议以此方式编写自定义行为。您必须遵循Observable协议,例如:
public class EmptyResponseOperator implements ObservableOperator<MyResponse, MyResponse> {
@Override
public Observer<? super MyResponse> apply(Observer<? super MyResponse> observer)
throws Exception {
return new DisposableObserver<MyResponse>() {
// -------------------------------------
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
@Override
public void onStart() {
observer.onSubscribe(this);
}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// -------------------------------------
@Override
public void onNext(MyResponse myResponse) {
dispose(); // <-------------------------------------------------------
if (myResponse.getTotalResultsCount() == 0) {
observer.onError(new ApiException("Search found 0 results"));
} else {
observer.onNext(myResponse);
observer.onComplete();
}
}
@Override
public void onError(Throwable e) {
if (!isDisposed()) { // <---------------------------------------
observer.onError(e);
}
}
@Override
public void onComplete() {
if (!isDisposed()) { // <---------------------------------------
observer.onComplete();
}
}
};
}
}