在 Android 项目中使用响应式编程的 Junit

Junit with Reactive Programming in Android project

我正在尝试在 Android 项目中使用 JUnit4,我也在该项目中使用 RxAndroid/RxJava。

我所做的是使用 retrofit

UUID generator 调用 REST API

UUIDApi.java只是一个retrofit调用的接口(现在只有一个)

public interface UUIDApi {

    static final String BASE_URL = "https://www.uuidgenerator.net";

    @GET("/api/version4")
    Observable<String> getUUID();
}

UUIDModel.javaretrofit初始化的地方和上面写的接口实现的地方

public class UUIDModel implements UUIDApi{
    private Retrofit retrofit;
    private UUIDApi uuidApi;
    UUIDObserver uuidObserver = new UUIDObserver();

    public UUIDModel() {
        retrofit = new Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(new ToStringConverterFactory())
                .baseUrl(UUIDApi.BASE_URL)
                .build();
        uuidApi = retrofit.create(UUIDApi.class);
    }

    @Override
    public Observable<String> getUUID() {
        return uuidApi.getUUID();
    }

    public void generateUUID(){
        Observable<String> observable =  this.getUUID();
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(uuidObserver);
    }
}

比起我的 UUIDObserver,它只是一个实现 Observer 的 class。

注意:新的 ToStringConverterFactory 是 class 我发现

使用模拟器执行这段代码,我确信它工作正常。 问题是我不明白如何合并这段代码,因为使用rxAndroid/rxJava它会在另一个线程中执行。

我读到:

The official way to test an observable is by using a TestSubscriber, an helper subscriber provided directly by the RxJava library.

所以我试过了

@Test
    public void test_uuid() throws Exception {
        UUIDApi uuidApi = new UUIDModel();
        Observable<String> observable = uuidApi.getUUID();

        TestSubscriber<String> testSubscriber = new TestSubscriber<>();
        observable.subscribe(testSubscriber);

    }

但在 observable.subscribe(testSubscriber); 我收到错误“无法解析方法 'subscribe(io.reactivex.subscribers.TestSubscriber)'

我做错了什么?我应该如何应对 rxProgramming 和 JUnit?

我正在这样测试 RxJava + Retrofit :

首先,我使用 Schedulers.trampoline() 进行测试。 然后在基本单元测试中:

@Mock
ResponseBody mockResponseBody;

@Test
public void testCondition(){
    when(mService.operation()).thenReturn(Observable.just(response));

    mPresenter.handleOperation();

    verify(mView).operationResult();
}

我正在测试 3 个案例:成功响应(200-300 之间)、错误响应、失败

测试成功:response = Response.success(your_body);

测试错误:response= Response.error(any_error_code,mockResponseBody);

对于测试失败:只是 return Observable.error(); inside thenReturn

在此单元测试中,我们正在模拟我们的网络服务调用,它从不依赖于网络服务,因此您可以 运行 即使离线也可以进行单元测试。

但如果您想查看真正的网络服务调用,您可以编写集成测试。

TestSubscriberFlowable 相关,而 TestObserverObservable 相关。但对于两者而言,您实际上不必手动订阅任何内容。您只需使用 test() 方法即可。

observable.test()
      .assertNoErrors()
      .assertValue(expected)
      .assertComplete();

您可以利用 test 运算符将您的 Observable 订阅到 TestObserver,它记录事件并允许您对它们做出断言:

observable
    .test()
    .assertValue(...)
    .assertComplete()
    //etc

要处理反应流中的异步操作,您可以尝试这些方法:

  • 利用TestObserver方便的await运算符,等待TestObserver收到onErroronComplete事件。

  • 通过依赖注入(例如构造函数注入)提供 Schedulers,因此您可以在测试中用 Schedulers.trampoline.

  • 替换它们
  • 使用 RxJava 的钩子函数之一(例如 RxJavaPlugins.setInitIoSchedulerHandler)更改异步 Scheduler 的默认实现。