验证失败-未调用函数

时间:2020-06-13 17:49:38

标签: unit-testing kotlin mockk

我正在尝试测试这样的功能:

override suspend fun create(item: Location): FlowResult<Location> {
    val (base, version) = locationRepositoryMapper.map(item)
    return locationRemoteSource.create(base, version)
        .flatMapConcat {
            when (it) {
                is Result.Success -> {
                    locationLocalSource.create(
                        base = it.data.first,
                        version = it.data.second
                    )
                }
                else -> flowOf(it)
            }
        }.mapToModel()
}

测试本身:

@Test
fun `during creating, when data were saved into the remote source and failed to save it locally, then an error should be returned`() =
    runTest {
        // setup
        coEvery { locationRemoteSource.create(any(), any()) } returns flowOf(Result.Success(locationPair))
        coEvery { locationLocalSource.create(any(), any()) } returns flowOf(Result.Failure(mockk()))
        coEvery { locationRepositoryMapper.map(any()) } returns locationPair
        // invoke
        val result = repository.create(mockk())
        // verification
        coVerify(exactly = 1) { locationRemoteSource.create(any(), any()) }
        coVerify(exactly = 1) { locationLocalSource.create(any(), any()) }
        // assertion
        result.collect {
            assertTrue(it.isFailure)
        }
    }

在线失败的问题:

coVerify(exactly = 1) { locationLocalSource.create(any(), any()) }

它打印出未调用 locationLocalSource

Verification failed: call 1 of 1: LocationLocalSource(#3).create(any(), any(), any())) was not called

我不知道为什么会这样,因为根据我的理解,如果远程源返回成功结果,那么应该调用从本地源创建乐趣。我哪里错了?预先谢谢你。

P.S。验证远程源通过没有问题

更新#1:测试类中LocationLocalSource类的定义

private val locationPair = Pair(mockk<LocationBase>(), mockk<LocationVersion>())
private val locationLocalSource = mockk<LocationLocalSource>()
private val locationRemoteSource = mockk<LocationRemoteSource>()
private val locationRepositoryMapper = mockk<RepositoryMapper<Location, LocationBase, LocationVersion>>()
private val repository = LocationRepositoryImpl(
    locationLocalSource = locationLocalSource,
    locationRemoteSource = locationRemoteSource,
    locationRepositoryMapper = locationRepositoryMapper
)

1 个答案:

答案 0 :(得分:0)

简而言之:

1。像这样修改测试乐趣:

// invoke
val result = runTest {
  repository.create(mockk())
}

2.modify runTest的乐趣:

fun <T> runTest(block: suspend () -> Flow<T>): List<T> {
    val result = mutableListOf<T>()
    runBlockingTest {
        launch {
            block()
                .onStart {
                    println("${Instant.now()}: starts")
                }
                .onEach {
                    println("${Instant.now()}: $it")
                }
                .onCompletion { ex -> ex?.let {
                    println("${Instant.now()}: $it") }
                }
                .collect {
                    result.add(it)
                }
        }
    }
    return result
}