单元测试:如何验证和模拟 Android 中 RxJava 中的 Observable 的 onCompleted

gre*_*qrl 4 android unit-testing mockito rx-java

我正在尝试为使用 Retrofit 2、Mockito 1.10 和 RXJava 1.0 的 Android 应用程序编写一些单元测试。我没有使用支持 lambda 的 Java 版本!

我的代码使用 Observables,我可以执行以下操作:

when(myAPI.Complete(anyString(), any(MyContainer.class)))
        .thenReturn(Observable.<GenericResponse>error(new Throwable("An error has occurred!")));

Subscriber genericResponseSubscriber = mock(Subscriber.class);

myPresenter.myUseCase(id, container, genericResponseSubscriber);

verify(genericResponseSubscriber, times(1)).onError(any(Throwable.class));
Run Code Online (Sandbox Code Playgroud)

上面的代码工作正常,并允许我抛出错误并在测试中捕获它。

我也需要做的(当然):) 是捕捉积极的条件。我觉得这很明显,但找不到我需要的答案。

如何捕获 onComplete 和 onNext 案例?

我知道 onComplete 的验证将是......

验证(genericResponseSubscriber, times(1)).onCompleted();

但我看不出我的“何时”条款应该是什么。我尝试了以下但失败了:

GenericResponse response = new GenericResponse();
response.setSuccess(true);

when(myAPI.orderComplete(anyString(), any(MyContainer.class)))
        .thenReturn(Observable.just(response));

Subscriber genericResponseSubscriber = mock(Subscriber.class);

myPresenter.myUseCase(id, container, genericResponseSubscriber);

verify(genericResponseSubscriber, times(1)).onCompleted();
Run Code Online (Sandbox Code Playgroud)

这里的失败是subscriber.onStart() 被调用了。

所以,我想知道的是,我如何模拟和验证“onComplete”和“onNext”调用,更重要的是我应该看起来能够自己解决这个问题而不是问!:)

与往常一样,任何帮助表示赞赏。

编辑..

我的 onError 工作测试用例..

    public void UseCaseOnError() throws Exception {?        
     String id = "5";?    ?        
     order Order = new Order();?        
     SomeContainer myContainer = new SomeContainer(order);?    ?        

     when(myRetroFitAPI.complete(anyString(), any(SomeContainer.class)))
Run Code Online (Sandbox Code Playgroud)

.thenReturn(Observable.error(new Throwable(“我的错误!”)));? ?

     Subscriber genericResponseSubscriber = mock(Subscriber.class);?    ?        

     orderPresenter.doUseCase(id, myContainer, genericResponseSubscriber);?    ?        

     verify(genericResponseSubscriber,times(1)).onError(any(Throwable.class));?    ?    

}
Run Code Online (Sandbox Code Playgroud)

我真正应该补充的是,我觉得就积极状态而言,onError 应该有一个等价物,即 onCompleted。如果我这样做但使用 onCompleted 代替,我的验证将失败,因为它检测到 onStart 已被调用,而我发现这相当令人困惑。

我曾尝试使用 ReplaySubject 如下:

public void createOrderOnCompleteError() {
    orderOnCompleteSubject.onError(new Throwable("I am an error"));
}

public void createOrderOnCompleteSuccess() {
    orderOnCompleteSubject.onNext(new GenericResponse().setSuccess(true));
    orderOnCompleteSubject.onCompleted();
}
Run Code Online (Sandbox Code Playgroud)

错误机制工作正常......完成的机制不......

GVi*_*i82 6

您应该以这种方式使用该类TestObserver来测试Observable

public Observable<Integer> getObservable() {
     return Observable.just(12, 20, 330);
}

@Test
public void testObservable() {
     Observable<Integer> obs = getObservable();
     TestObserver<Integer> testObserver = TestObserver.create();
     obs.subscribe(testObserver);

     testObserver.assertComplete();
     testObserver.assertResult(12, 20, 330);
 }
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以验证它是否完成并发出所有预期的项目。

如果你想创建一个可观察的模拟版本,你可以创建一个Observable具有你想要的行为的新版本。例如:

public Observable<Integer> mockedObservableCompleteWithResult() {
        return Observable.create(e -> {
            e.onNext(12);
            e.onNext(20);
            e.onNext(330);
            e.onComplete();
        });
    }
Run Code Online (Sandbox Code Playgroud)

可以通过上述测试进行验证。

然后我们可以创建其他模拟来对其他结果进行建模

public Observable<Integer> mockedObservableError() {
            return Observable.create(e -> {
                e.onNext(12);
                e.onError(new Throwable("Generic exception"));
            });
        }
Run Code Online (Sandbox Code Playgroud)

这可以验证:

@Test
public void testObservable() throws Exception {
       Observable<Integer> obs = mockedObservableError();
       TestObserver<Integer> testObserver = TestObserver.create();
       obs.subscribe(testObserver);

       testObserver.assertError(Throwable.class);
}
Run Code Online (Sandbox Code Playgroud)