我有以下逻辑用于从可完成(带有doOnComplete
回调)创建可观察数据,这是经过单元测试的:
class ObservableSrc(val completableSrc: CompletableSrc) {
fun getObservable(client: Client): Observable<State> {
return client.getResults()
.concatMap { processResult(client, it.values) }
}
private fun processResult(Client: Client, values: Values): Observable<State> =
completableSrc.getCompletable(client.type, values)
.doOnComplete { client.doSomething(values)}
.toSingleDefault(…)
.map { … }
.toObservable()
.startWith(State.InProgress)
}
@Test
fun test() {
whenever(client.type).doReturn(Type.SOME_TYPE)
whenever(client.getResults()).doReturn(Observable.just<Result>(Result(mock())))
whenever(completableSrc.getCompletable(any(), any())).doReturn(Completable.complete())
doNothing().whenever(client).doSomething(any())
val observer = tested.getObservable(client).test()
observer.assertComplete()
verify(completableSrc, times(1)).getCompletable(any(), any())
verify(client, times(1)).doSomething(any())
}
问题是验证doSomething
给出了与模拟client
有 2 个交互,但没有调用所需的方法。我发现如果我像这样改变链接:
completableSrc.getCompletable(client.type, values)
.toSingleDefault(…)
.map { … }
.doOnSuccess { client.doSomething(values)}
.toObservable()
.startWith(State.InProgress)
然后它起作用了。我只是不知道为什么带有doOnComplete
的先前版本失败(observer.assertComplete()
成功执行)。 似乎它被释放得太早了,所以没有调用回调,但为什么?
更新
使用单元测试和模拟测试代码。我使用kolin.test和mockk来满足个人喜好。
interface CompletableSrc {
fun getCompletable(): Completable
}
interface Client {
fun doSomething()
fun doSomethingElse()
}
class CompletableTest {
@Test
fun `functions doOnComplete and doOnSuccess should work as expected`() {
val completableSrc: CompletableSrc = mockk {
every { getCompletable() } returns Completable.complete()
}
val client: Client = mockk {
every { doSomething() } returns Unit
every { doSomethingElse() } returns Unit
}
val observable = completableSrc.getCompletable()
.doOnComplete { client.doSomething() }
.toSingleDefault(0)
.map { it + 1 }
.doOnSuccess { client.doSomethingElse() }
.toObservable()
.startWith(-1)
val test = observable.test()
test.assertComplete()
test.assertValues(-1, 1)
verify(exactly = 1) {
completableSrc.getCompletable()
client.doSomething()
client.doSomethingElse()
}
}
}
如您所见,断言和模拟验证都成功了。
以前
您的代码应该可以正常工作,对我来说真的很难说出了什么问题,因为我无法运行它,但是我创建了一个代码片段,它正在做几乎相同的事情并且它按预期工作。
例
fun main(args: Array<String>) {
var sideEffect = 0
val observable = Completable.complete()
.doOnComplete { sideEffect += 1 }
.toSingleDefault(sideEffect)
.map { sideEffect + 1 }
.doOnSuccess(::println)
.toObservable()
.startWith(-1)
val test = observable.test()
test.assertComplete()
test.assertValues(-1, 2)
}
输出
2
执行副作用函数Completable.doOnComplete
和Single.doOnSuccess
,更新变量sideEffect
并打印到控制台。