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

时间:2017-07-06 13:05:28

标签: android unit-testing mockito rx-java

我正在尝试为使用Retrofit 2,Mockito 1.10和RXJava 1.0的Android应用程序编写一些单元测试。我没有使用支持lambdas的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));

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

我需要能够做的(当然):)是捕捉积极的条件。我觉得它显而易见但无法找到我需要的答案。

如何捕获onComplete和onNext案例?

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

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

但我无法看到我的&#39;何时&#39;条款应该是。我尝试了以下但是失败了:

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();

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

所以,我想知道的是,我如何模拟和验证“完成”&#39;和&#39; onNext&#39;请打电话,更重要的是我应该看到能够自己解决这个问题,而不是要问! :)

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

编辑..

我的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)))

.thenReturn(Observable.error(new Throwable(“我的错误!&#34;)));

     Subscriber genericResponseSubscriber = mock(Subscriber.class);
    
        

     orderPresenter.doUseCase(id, myContainer, genericResponseSubscriber);
    
        

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

}

我真正应该补充的是,我认为在正状态方面应该存在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();
}

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

3 个答案:

答案 0 :(得分:3)

您应该使用课程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);
 }

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

如果要创建observable的模拟版本,可以创建一个具有所需行为的新Observable。例如:

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

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

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

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

可以验证:

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

       testObserver.assertError(Throwable.class);
}

答案 1 :(得分:1)

您应该为RxJava 1创建一个TestSubscriber而不是模拟订阅服务器:

id

您可能需要更具体地了解您期望的错误类。查看TestSubscriber documention。您可以通过此课程验证更多内容。

快乐测试!

答案 2 :(得分:0)

最简单的方法是尝试抛出一个模拟异常,而不是真正的异常。

@Mock
Exception mockException;

observer.onError(mockException);