当前位置: 首页 > 知识库问答 >
问题:

单元测试:如何验证和模拟在Android中的RxJava中完成一个可观察的

桓瀚
2023-03-14

我试图写一些单元测试的Android应用程序是使用改造2, Mockito 1.10和RXJava 1.0.我没有使用支持lambdas的java版本!

我的代码使用可观测的,我可以做到以下几点:

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,次(1))。未完成();

但我看不出我的when子句应该是什么。我尝试了以下方法,但失败了:

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

因此,我想知道的是,我如何模拟和验证“onComplete”和“onNext”调用,更重要的是,我本应该自己解决这个问题,而不是去问!)

和往常一样,我们非常感谢您的帮助。

编辑

我的一个错误工作测试用例。。

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

     when(myRetroFitAPI.complete(anyString(), any(SomeContainer.class)))

.然后返回(Observable.error(新的Throwable(“我的错误”));
 


     Subscriber genericResponseSubscriber = mock(Subscriber.class);
    
        

     orderPresenter.doUseCase(id, myContainer, genericResponseSubscriber);
    
        

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

}

我真正需要补充的是,我觉得就积极状态而言,onError应该有一个等价物,即未完成。如果我也这样做,但使用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个答案

吕俊才
2023-03-14

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

@Mock
Exception mockException;

observer.onError(mockException); 
岳俊晖
2023-03-14

您应该为RxJava 1创建一个测试订阅服务器,而不是嘲笑订阅服务器:

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

TestSubscriber genericResponseSubscriber = TestSubscriber.create();

myPresenter.myUseCase(id, container, genericResponseSubscriber);

// To check for an error
genericResponseSubscriber.assertError(Throwable.class)

// To check for completion
genericResponseSubscriber.assertCompleted()

您可能需要更具体地说明您期望的错误类。查看测试订阅者文档。你可以用这个类验证很多东西。

快乐测试!

缑赤岩
2023-03-14

您应该使用类Test观察员测试可观察的,通过以下方式:

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);
}
 类似资料:
  • 我如何在RxJava中创建一个从不同的地方完成的对象(未来),但我想要向某个客户端返回一个可观察的对象?

  • 我目前在Android和Kotlin上使用RxJava,但我有一个问题,如果不使用toBlocking(),我无法解决。 我在员工服务中有一个方法,它返回一个可观察的 这一切都很好,因为每当员工发生变化时,这个可观察对象就会发出新的员工列表。但是我想从员工那里生成一个PDF文件,这显然不需要每次员工更改时都运行。另外,我想从PDF生成器方法返回一个可完成的对象。我想在PDF中添加一个标题,然后遍历

  • 我有多个热观测器,它们可能发射也可能不发射项目。因此,我想把可观察项组合起来,然后如果其中任何一个发出结果,就处理结果,但如果其他可观察项在item发出,就应该一起处理。 还有可能在之前发出 最接近我所需要的,但只有当所有可观察到的对象发出至少一个项时才会发出结果。这个有无反应操作符吗?

  • 假设存在包含方法的接口: 实现combinedCall方法的最佳方法是什么: 从makeHttpCall获取数据 使用store InDatabase存储它 返回在store InDatabase完成时完成的完成? 似乎在RxJava 1.0中可以执行Completable.merge(可观察),但合并似乎不再接受可观察。

  • 我是从Android的角度问这个问题的,但这应该适用于RxJava。 作为一个最佳实践,我的视图是否应该总是处理即使是短期的、、和终止Rx类型,这些类型应该以短的顺序终止,但在用户关闭视图时仍然可以执行?我知道当Rx链终止时,它会被释放,但这可能发生在视图关闭后的某个时间。 例如,执行HTTP GET的。调用将完成,但可能是在视图被破坏之后,暂时阻止了垃圾回收。 如果使用在长寿命视图中收集此类时,

  • 问题内容: 给定汽车清单(),我可以这样做: 有没有办法我可以从一个到一个序列? 像没有参数的东西 问题答案: 您可以这样映射到: 请注意,flatMapping可能不会保留源可观察的顺序。如果订单对您很重要,请使用。

  • 我对RxJava并不完全陌生,但我被一项看似简单的任务所阻碍。 我有一个数据源,它公开了一个反应式API,我所要做的就是获取一些数据,返回它,并在没有其他消息发出时自动关闭连接。 这是我的代码: conn.query()和conn.close()在不同的调度程序中异步执行。此代码不起作用,因为conn.close()返回一个没有订阅服务器的Completable。此外,如果我手动订阅doOnCom

  • 我正在从事一个涉及Hystrix的项目,我决定使用RxJava。现在,忘记Hystrix的其余部分,因为我相信主要问题是我完全搞砸了正确编写可观察代码。 需要:我需要一种方法来返回一个代表多个可观察对象的可观察对象,每个可观察对象都运行一个用户任务。我希望该可观察对象能够返回任务的所有结果,甚至错误。 问题:可观测流会因错误而消亡。如果我有三个任务,而第二个任务引发了一个异常,那么即使第三个任务成