我正在尝试测试一个类,该类采用
LiveData
对象,将其转换为流,收集它,并根据结果执行操作。
它在主代码中按预期工作,但我不知道如何测试它。看起来
collect
内的代码块发生的验证从未达到,并且测试错误地通过了。
这是我的设置:
class LiveDataClass {
fun liveData(): LiveData<Boolean> {
return MutableLiveData(true)
}
fun doSomething() {}
fun decoyMethod() {} // to verify if it's called in the test, just to make it fail
}
收集流量的类:
class FlowClass(private val liveDataClass: LiveDataClass) {
suspend fun doSomethingWhenLiveDataIsTrue() {
liveDataClass.liveData().asFlow().collect {
if (it) {
println("Inside the collection")
liveDataClass.doSomething() // we reach the code here in the test
}
}
}
}
还有测试 - 我已经查看了多个设置示例以避免错误,即使此测试通过,并且我看到
liveDataClass.doSomething()
被调用,验证也从未发生。
我验证
liveDataClass.decoyMethod()
是否曾经被调用过(事实上并没有)并且测试仍然没问题......
class FlowClassTest {
@get:Rule
val instantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
private val dispatcher = StandardTestDispatcher()
private val testScope = TestScope(dispatcher)
@Before
fun setUp() {
Dispatchers.setMain(dispatcher)
}
@After
fun tearDown() {
Dispatchers.resetMain()
}
@Test
fun test() = runTest {
testScope.launch {
println("Starting up the test case")
val liveDataClass: LiveDataClass = mockk {
every { liveData() } returns MutableLiveData(true)
every { doSomething() } answers {
println("TEST - Doing something")
}
}
val flowClass = FlowClass(liveDataClass)
flowClass.doSomethingWhenLiveDataIsTrue()
verify { // never happens and the test passes even though it shouldn't!
println("Verifying")
liveDataClass.decoyMethod()
}
}
}
}
如何设置此测试,使其真正有用并正确验证调用?
您正在使用 runTest 将测试作为协程运行。在此块内,您将使用 testScope.launch 启动另一个协程。这个嵌套协程是不必要的,可以删除。
尝试以下方法
@Test
fun test() = runTest {
println("Starting up the test case")
val liveDataClass: LiveDataClass = mockk {
every { liveData() } returns MutableLiveData(true)
every { doSomething() } answers {
println("TEST - Doing something")
}
}
val flowClass = FlowClass(liveDataClass)
flowClass.doSomethingWhenLiveDataIsTrue()
verify {
println("Verifying")
liveDataClass.doSomething() // Verify that this method was called
}
}