RxJava Observables 单元测试
RxJava 是一个非常棒的类库,但是它不容易上手,在这里,我们列出了不同的方法来对 Observables 进行单元测试。
在 ribot 时,我们几个月前开始使用 RxJava,而现在它已经成为我们开发的安卓应用的核心架构元素。使用 RxJava 有很多益处,但是学习(使用) 的过程是曲折的,很多时候,我们发现我们试图让自己的头脑中环绕着那些解释操作过程如何工作的“美丽”蓝图。
改变我们架构的第一步就是改变那些定义在数据层的方法,让他们返回 Observables。下一个问题是:我们如何对此进行单元测试?
丑陋的方式
我们头脑中首先想到的是以同样的方式简单地描述我们的外部测试结果,然后将结果保存在一个全局变量,可以在以后进行断言。例如,假设我们有一个方法在一个 database helper 类中,负责加载用户对象。
public Observable<User> loadUser() {
...
}
然后,针对这个方法的测试就会如同下面这样:
User mUser;
@Test
public void shouldLoadUser() throw Exception {
databaseHelper.loadUser()
.subscribe(new Action1<User>() {
@Override
public void call(User user) {
mUser = user;
}
});
assertNotNull(mUser);
}
默认情况下,这段代码将会执行,因为 Observable 会在同一个线程上执行。 因此,在结果设置为全局变量后断言会一直执行。
更好的方式
我们很快意识到先前的解决方式是不完美的。尽管先前的方法能够工作,(但是) 它需要大量的模版代码。所以,我们决定创建一个类,该类提供一个名称为 subscribeAssertingThat() 的静态方法。这个类允许我们 subscribe 一个 observable,保存测试结果并且以一种清晰的方式执行一些断言。例如:
@Test
public void shouldLoadTwoUsers() throw Exception {
subscribeAssertingThat(databaseHelper.loadUser())
.completesSuccessfully()
.hasSize(2)
.emits(user1, user2)
}
通过 100 行左右的代码,我们称为 RxAssertions 的这个类使我们的测试可读性和可写性更好。你可以在 这里 找到 RxAssertions 类的代码。
标准方式
后来,我们发现 RxJava 提供了一个称为 TestSubscriber 的 subscriber 专用类型。
TestSubscriber 由各种各样的 Subscriber (组成),你可以用于单元测试,执行断言,检查接收到的事件,或封装 mocked 类型的 Subscriber。
与第二个解决方案类似,测试 subscriber 允许你通过结果执行断言。例如:
@Test
public void shouldLoadTwoUsers() throw Exception {
TestSubscriber<User> testSubscriber = new TestSubscriber<>();
databaseHelper.loadUser().subscribe(testSubscriber);
testSubscriber.assertNoErrors();
testSubscriber.assertReceivedOnNext(Arrays.asList(user1, user2))
}
我们还没有频繁的使用 TestSubscriber,但你可以看到上面的代码是相当优雅和可读。除了不同的断言,通过 Observable 调用 getOnNextEvents() 方法,它也允许你恢复整个发现的问题列表。
当使用 TestSubscriber 时,你会发现链接的断言是不可能的,因为断言方法不返回 TestSubscriber。这个能力将是一个很好的改善(方向)。
总结
TestSusbcriber 可能是目前最好的选择,因为它是 RxJava codebase 的一部分,它会不断的改进以及将新功能合并。能够了解别的开发者如何进行 Observables 的单元测试时很棒的。除了那些我在这里提到的其他方法,你还有什么方法(用于测试)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: gradle 技巧之语法浅谈
下一篇: 自动化截图-应用分发时的自动截图方案
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论