首页 > 解决方案 > 使用turtle测试协程StateFlow的更好方法是什么

问题描述

我正在寻找一种更好的方法来测试协程。目前,我正在使用Turbine作为测试助手。但是,我在改善超时问题时遇到了一些困难。

前任:

class RepositoryTest {

    @get:Rule
    val rule = InstantTaskExecutorRule()

    private lateinit var sut: SubjectToTest

    private val testDispatchers = TestDispatchersProvider.dispatchers

    private val mockAddressRepository = mockk<AddressRepository>(relaxed = true)
    private val mockApiService = mockk<ApiService>(relaxed = true)
    private val mockCardsRepository = mockk<CardsRepository>(relaxed = true)

    @Before
    fun setup() {

         sut = SutRepository(
            apiService = mockApiService,
            dispatchersProvider = testDispatchers,
            restCallHandler = testRestCallHandler,
            addressRepo = mockAddressRepository,
            cardRepo = mockCardsRepository,
        )
    }

    @After
    fun tearDown() {
        unmockkAll()
    }

    private val mockCardResponse = CardResponse(
        data = DataModel(
            listOf(
                ...
            )
        )
    )


    @Test
    fun `fetchData has success response then return Data`() = runBlockingTest {
        // Given
        coEvery {
            mockAddressService.fetchAddresss(any(), any(), any(), any(), any(), any(), any())
        } returns Response.success(mockCardResponse)
        every {
            mockCardsRepository.fetchCard
        } returns mockFlow()

        testRestCallHandler.callResult = ...

        // Test
        sut.fetchMessages(true)
        sut.StateFlow.test {
            expectItem().assertObject{ ... }
            expectItem().assertSize(1)
        }

    }
}

上面的代码有TimeoutCancellationException

kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms

    at |b|b|b(Coroutine boundary.|b(|b)

通过解决上述问题,我在测试中移动了类初始化。

    @Test
    fun `fetchData has success response then return Data`() = runBlockingTest {
        // Given
        coEvery {
            mockAddressService.fetchAddresss(any(), any(), any(), any(), any(), any(), any())
        } returns Response.success(mockCardResponse)
        every {
            mockCardsRepository.fetchCard
        } returns mockFlow()

        testRestCallHandler.callResult = ...

        // Test
        sut = SutRepository(
            apiService = mockApiService,
            dispatchersProvider = testDispatchers,
            restCallHandler = testRestCallHandler,
            addressRepo = mockAddressRepository,
            cardRepo = mockCardsRepository,
        )
        sut.fetchMessages(true)
        sut.StateFlow.test {
            expectItem().assertType<List<DataMode;>> {
                this.assertListSize(1)
            }
            cancel()
        }
    }

在测试中移动初始化后,测试通过但我正在寻找一种改进它的方法。

标签: androidkotlin-coroutineskotlin-stateflow

解决方案


推荐阅读