如何测试非RxJava observable或异步代码?

时间:2016-08-18 08:00:54

标签: java unit-testing testing asynchronous reactive-programming

我正在玩实现我自己的观察者或者用其他语言移植它们以获得乐趣和利润。

我遇到的问题是,关于如何正确测试observable或异步代码的信息非常少。

考虑以下测试代码:

// Create a stream of values emitted every 100 milliseconds
// `interval` uses Timer internally
final Stream<Number> stream = 
  Streams.interval(100).map(number -> number.intValue() * 10);

ArrayList<Number> expected = new ArrayList<>();

expected.add(0);
expected.add(10);
expected.add(20);

IObserver<Number> observer = new IObserver<Number>() {
  public void next(Number x) {
    assertEquals(x, expected.get(0));
    expected.remove(0);
    if(expected.size() == 0) {
      stream.unsubscribe(this);
    }
  }
  public void error(Exception e) {}
  public void complete() {}
};

stream.subscribe(observer);

订阅流后,它会发出第一个值。调用onNext ...然后测试成功退出。

在JavaScript中,现在大多数测试框架都为测试用例提供了一个可选的Promise,您可以在成功/失败时异步调用它。是否有类似的Java可用?

1 个答案:

答案 0 :(得分:1)

由于执行是异步的,你必须等到完成。你可以用一种旧的方式等待一段时间

 your_code
 wait(1000)
 check results.

或者,如果您使用Observables,则可以使用 TestSubscriber 在这个例子中,你可以看到我们等待观察者消耗所有项目之后是否有异步操作。

@Test
public void testObservableAsync() throws InterruptedException {
    Subscription subscription = Observable.from(numbers)
            .doOnNext(increaseTotalItemsEmitted())
            .subscribeOn(Schedulers.newThread())
            .subscribe(number -> System.out.println("Items emitted:" + total));
    System.out.println("I finish before the observable finish.  Items emitted:" + total);


    new TestSubscriber((Observer) subscription)
            .awaitTerminalEvent(100, TimeUnit.MILLISECONDS);
}

您可以在此处查看更多异步示例https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/scheduler/ObservableAsynchronous.java