我正在尝试测试在Rxjava运算符之一的回调函数中编写的代码。这是我想要测试的原始代码
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="row">
<div class="col-sm-2 leftMenu"></div>
<div class="col-sm-10 pageContent"></div>
</div>
在上面的代码中有一个“map”运算符,它的回调函数将通过调用@Override
public Observable<List<User>> getUsers() {
UserDataStore userDataStore = userDataStoreFactory.createCloudDataStore();
return userDataStore.getUsers().map(userEntityDataMapper::transform);
}
方法将原始对象转换为另一个。 这里我想测试userEntityDataMapper的转换方法必须调用。这是我试图检查userEntityDataMapper.transform()
方法是否调用的代码。
userEntityDataMapper.transform()
我在stackoverflow和论坛上检查了许多类似的问题,但无法找到我问题的确切解决方案。
更新 以下是我为解决问题所做的更改。
@Test
public void testGetUsersHappyCase() {
List<UserEntity> userEntityList = new ArrayList<>();
userEntityList.add(new UserEntity());
given(mockUserDataStore.getUsers()).willReturn(Observable.just(userEntityList));
List<User> userList = new ArrayList<>();
given(mockUserEntityDataMapper.transform(userEntityList)).willReturn(userList);
given(mockUserDataStoreFactory.createCloudDataStore()).willReturn(mockUserDataStore);
Observable observable = userDataRepository.getUsers();
verify(mockUserDataStoreFactory).createCloudDataStore();
verify(mockUserDataStore).getUsers();
TestObserver<List<UserEntity>> testObserver = new TestObserver<>();
TestScheduler testScheduler = new TestScheduler();
observable.subscribeOn(testScheduler).observeOn(testScheduler).subscribeWith(testObserver);
verify(mockUserEntityDataMapper).transform(any(List.class));
}
感谢@tynn提示test()方法。我在{{3}}上找到的BasicRxJavaSample演示中也发现了同样的事情。
答案 0 :(得分:2)
您必须订阅流才能执行它。这可以像在observable上调用test()
一样容易。这将为您提供TestObserver
。
除此之外,您没有任何理由使用TestScheduler
。在你的情况下,它实际上是问题。您没有致电triggerActions()
,因此您的信息流根本没有被执行。
如果您没有修改您正在测试的代码中的任何调度程序,请在测试中忽略这些调度程序。如果需要更改它,则应该更好地创建规则,将Schedulers
设置为同步版本。您可以使用RxJavaPlugins
类找到此设置器。
答案 1 :(得分:0)
Tynn的回答是正确的,你应该听听那里的建议。重构的测试看起来像这样:
@org.junit.Test
public void testUserDataRepository() throws Exception {
//arrange
List<UserEntity> userEntityList = new ArrayList<>();
userEntityList.add(new UserEntity());
given(mockUserDataStore.getUsers()).willReturn(Observable.just(userEntityList));
List<User> userList = new ArrayList<>();
given(mockUserEntityDataMapper.transform(userEntityList)).willReturn(userList);
given(mockUserDataStoreFactory.createCloudDataStore()).willReturn(mockUserDataStore);
//act
TestObserver<List<User>> testObservable = userDataRepository.getUsers().test();
//assert
verify(mockUserDataStoreFactory).createCloudDataStore();
verify(mockUserDataStore).getUsers();
verify(mockUserEntityDataMapper).transform(any(List.class));
}
然而,这种白盒测试存在更大的问题 - 测试已经退化为被测系统的重新实现。
如果UserEntityDataMapper
是轻量级的,您可以在测试中使用它的真实版本。那么你的测试就变成了黑盒子测试,可以说它具有更多的价值。您将知道UserEntityDataMapper#transform
的调用是通过对List<User>
的正确结果的断言发生的:
@org.junit.Test
public void testUserDataRepository() throws Exception {
//arrange
List<UserEntity> userEntityList = new ArrayList<>();
userEntityList.add(new UserEntity());
given(mockUserDataStore.getUsers()).willReturn(Observable.just(userEntityList));
List<User> userList = new ArrayList<>();
given(mockUserDataStoreFactory.createCloudDataStore()).willReturn(mockUserDataStore);
//act
TestObserver<List<User>> testObservable = userDataRepository.getUsers().test();
//assert
testObservable.assertResult(userList);
}