Jam*_*mal 4 android unit-testing rx-android rx-java2
我在 ViewModel 中有一个重复的可观察对象,如下所示:
class MainViewModel @Inject constructor(private val ratesUseCase: RatesUseCase) : ViewModel() {
private var disposable: Disposable? = null
private val resultLiveData = MutableLiveData<Resource<Map<String, Double>>>()
fun result() = resultLiveData
fun getRates(base: String) {
disposable = Observable
.interval(1, TimeUnit.SECONDS)
.flatMap { ratesUseCase.execute(base) }
.doOnSubscribe { publishResult(Resource.loading(mapOf())) }
.subscribe(
{
publishResult(Resource.success(values))
},
{
publishResult(Resource.error(it.localizedMessage, mapOf()))
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
我想测试 getRates 函数。它总是返回 LOADING 状态 这里缺少什么?
测试用例 :
@Test
fun executeSuccess() {
val base = "CANARY"
whenever(currencyRepository.getRates(base))
.thenReturn(Observable.just(map))
viewModel.result().observeForever(observer)
viewModel.getRates(base)
verify(observer).onChanged(Resource.success(map))
}
Run Code Online (Sandbox Code Playgroud)
如果你不传递Scheduler给Observable.interval.
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
public static Observable<Long> interval(long period, TimeUnit unit) {
return interval(period, period, unit, Schedulers.computation());
}
Run Code Online (Sandbox Code Playgroud)
它将Schedulers.computation()用作默认调度程序。
您的测试线程将完成,而interval不会发出任何内容。
你必须用来TestScheduler正确测试间隔。请参阅此处:
单元测试具有延迟的 Rxjava 可观察量
您可以覆盖计算调度程序或传递TestScheduler到Observable.interval您的 ViewModel。然后你可以TestScheduler.advanceTimeBy控制你的间隔排放。
我确实在这里修复了测试,这就是我是如何做到的。这里有两个可观察的:
1- 可观察interval()到1秒。
2- 可观察到的ratesUseCase.execute(base)。正如你在下面看到的,它是如何在里面MainViewModel
Observable
.interval(1, TimeUnit.SECONDS)
.flatMap { ratesUseCase.execute(base) }
.doOnSubscribe { publishResult(Resource.loading(mapOf())) }
.subscribe(
{
publishResult(Resource.success(values))
},
{
publishResult(Resource.error(it.localizedMessage, mapOf()))
}
)
Run Code Online (Sandbox Code Playgroud)
为了测试getRates在MainViewModel
1-注入测试调度程序 ratesUseCase.execute(base)
2-RxJavaPlugins.setComputationSchedulerHandler用于更改默认调度程序如下
@Before
fun setUp() {
val testScheduler = TestScheduler()
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
ratesUseCase = RatesUseCase(appSchedulers, currencyRepository)
viewModel = MainViewModel(ratesUseCase)
}
Run Code Online (Sandbox Code Playgroud)
3-testScheduler.advanceTimeTo用于测试interval。请不要这里的顺序很重要,如下所示:
3.a : 模拟仓库
3.b : 观察 ViewModel LiveData
3.c:提前时间间隔
3.d : 验证结果
val base = "BASE"
whenever(currencyRepository.getRates(base))
.thenReturn(Observable.just(map))
viewModel.result().observeForever(observer)
viewModel.getRates(base)
testScheduler.advanceTimeTo(1, TimeUnit.SECONDS)
verify(observer).onChanged(
Resource.success(map)
)
Run Code Online (Sandbox Code Playgroud)
完整的项目和测试用例可以在这里找到
| 归档时间: |
|
| 查看次数: |
2480 次 |
| 最近记录: |