单元测试 - 已订阅验证Observable

Kon*_*Man 11 java unit-testing mockito observable rx-java

我有这样的java代码

 mDataManager.getObservable("hello").subscribe( subscriber );
Run Code Online (Sandbox Code Playgroud)

我想要verify以下Observable.subscribe()

我试图模仿getObservable()verify

 Observable<Response> res = mock(Observable.class);
 when(mDataManager.getObservable("hello")).thenReturn(res);
 verify(res).subscribe();
Run Code Online (Sandbox Code Playgroud)

但是有一个错误

Caused by: java.lang.IllegalStateException: onSubscribe function can not be null.
at rx.Observable.subscribe(Observable.java:8167)
at rx.Observable.subscribe(Observable.java:8158)
at rx.Observable.subscribe(Observable.java:7962)
....
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: omni.neo.hk.omniapiservice.v4.model.external.UserLoginBean.class
at rx.exceptions.OnErrorThrowable.addValueAsLastCause(OnErrorThrowable.java:109)
at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:187)
at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82)
... 48 more
Run Code Online (Sandbox Code Playgroud)

我认为mock这里不可能是一个Observable,但是如果没有一个模拟的Observable我就做不到verify(res).subscribe()

在这种情况下的任何建议?

mic*_*mek 1

也许你可以将Observable.onSubscribe方法与RunTestOnContext规则一起使用?可以TestContext为您提供一个Async对象,仅在测试完成后才终止测试。我认为,如果您将其与此结合起来,Observable#doOnSubscribe就可以实现所需的行为。

然而,使用Async有时可能会有点混乱。在下面的示例中,如果从未订阅可观察对象,则该doOnSubscribe函数将永远不会被评估,并且您的测试也不会终止。

例子:

@RunWith(VertxUnitRunner.class)
public class SubscriptionTest {

  @Rule
  public RunTestOnContext vertxRule = new RunTestOnContext();

  @Test
  public void observableMustBeSubscribed(final TestContext context) {
    final Async async = context.async();
    final Observable<String> observable = Observable.just("hello").doOnSubscribe(async::complete);
    final Manager mock = mock(Manager.class);
    when(mock.getObservable()).thenReturn(observable);

    mock.getObservable().subscribe();
  }

  interface Manager {
    Observable<String> getObservable();
  }
}
Run Code Online (Sandbox Code Playgroud)