Unit testing RxJava observable已完成,但在单元测试中未触发doOnComplete回调
我使用以下逻辑从completable(使用Unit testing RxJava observable已完成,但在单元测试中未触发doOnComplete回调,unit-testing,junit,kotlin,mockito,rx-java2,Unit Testing,Junit,Kotlin,Mockito,Rx Java2,我使用以下逻辑从completable(使用doOnCompletecallback)创建可观察数据,该回调经过单元测试: class ObservableSrc(val completableSrc: CompletableSrc) { fun getObservable(client: Client): Observable<State> { return client.getResults() .concatMap { proc
doOnComplete
callback)创建可观察数据,该回调经过单元测试:
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())
}
然后它就起作用了。我只是不知道为什么以前版本的
doOnComplete
失败(observer.assertComplete()
成功执行)。似乎处理得太快了,所以没有调用回调,但原因是什么?更新
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)
}
使用单元测试和模拟测试代码。我使用kolin.test和mock作为个人偏好
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)
}
执行副作用函数
Completable.doOnComplete
和Single.doOnSuccess
,更新变量sideEffect
,并打印到控制台。更新
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)
}
使用单元测试和模拟测试代码。我使用kolin.test和mock作为个人偏好
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)
}
执行副作用函数
Completable.doOnComplete
和Single.doOnSuccess
,更新变量sideEffect
,并打印到控制台。这些链式方法调用中的任何一个都应该进入完成阶段吗?startWith来自哪里?据我所见,您正在将Completable
转换为Single
(.toSingleDefault(…)
),但是Single
没有startWith
(因为它只发出一个值,所以有意义)我的坏,startWith
来自调用toObservable
后的observable。我更新了问题。completable是一个网络调用(改用Rx),但它在单元测试中被模拟。completable是否应该在这些链式方法调用中达到完成阶段?startWith从何而来?据我所见,您正在将Completable
转换为Single
(.toSingleDefault(…)
),但是Single
没有startWith
(因为它只发出一个值,所以有意义)我的坏,startWith
来自调用toObservable
后的observable。我更新了问题。completable是一个网络调用(用Rx改装),但它在单元测试中被模拟了。你是对的,代码在应用程序中运行良好。您是否尝试使用JUnit运行它?因此在您的示例中,assertComplete
和verify
都是成功的。在我的矿井里只有assertComplete
。你能模拟doSomething
在交互中不做任何事情并看到结果吗?我会试着看看我的模拟,也许它们有问题。@Luke实际上它是被模拟的(every{doSomething()}返回单位
),否则它会抛出一个异常,我不知道。我的意思是使用完全“什么也不做”的mock(就像在我的代码中一样)。我试图在你的代码中反映我的代码,但我几乎没有想法。你是对的,代码在应用程序中运行良好。您是否尝试使用JUnit运行它?因此在您的示例中,assertComplete
和verify
都是成功的。在我的矿井里只有assertComplete
。你能模拟doSomething
在交互中不做任何事情并看到结果吗?我会试着看看我的模拟,也许它们有问题。@Luke实际上它是被模拟的(every{doSomething()}返回单位
),否则它会抛出一个异常,我不知道。我的意思是使用完全“什么也不做”的mock(就像在我的代码中一样)。我试图在你的代码中反映我的代码,但我几乎没有想法了。