从所有模块访问通用协程规则 - Android 单元测试

问题描述 投票:0回答:1

我有一个

TestWatcher
类实现
TestCoroutineScope
接口,如下所示:

@ExperimentalCoroutinesApi
class MainCoroutineRule(private val dispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) :
TestWatcher(),
TestCoroutineScope by TestCoroutineScope(dispatcher) {
    override fun starting(description: Description?) {
        super.starting(description)
        Dispatchers.setMain(dispatcher)
    }

    override fun finished(description: Description?) {
        super.finished(description)
        cleanupTestCoroutines()
        Dispatchers.resetMain()
    }
}

这用于使用 kotlin 协程向

ViewModelTest
提供 Looper,例如:

@RunWith(JUnit4::class)
class BlaViewModelTest {

    @get:Rule
    val instantExecutorRule = InstantTaskExecutorRule()

    @ExperimentalCoroutinesApi
    @get:Rule
    val coroutineRule = MainCoroutineRule()

    @MockK
    lateinit var blaUseCase: BlaUseCase

    private lateinit var blaViewModel: BlaViewModel

    @Before
    fun setup() {
        MockKAnnotations.init(this)
        blaViewModel = BlaViewModel(blaUseCase)
    }

    @Test
    fun testBla_Positive() {
        coEvery {
            blaUseCase.execute(any()).await()
        } returns Resource.Success(Bla("data"))

        blaViewModel.blaLiveData.observeForever {}
        blaViewModel.bla()

        assert(blaViewModel.blaLiveData.value != null)
        assert(blaViewModel.blaLiveData.value is Resource.Success)
        assert((blaViewModel.blaLiveData.value as? Resource.Success)?.value?.data == "data")
    }
}

我的问题是我只能从

MainCoroutineRule
保留的同一模块测试目录访问
BlaViewModelTest

如果我将

MainCoroutineRule
移动到公共模块中的测试目录,假设
base
BlaViewModelTest
在测试运行时无法访问
MainCoroutineRule
,最终失败。编译时没有问题。

我尝试将

MainCoroutineRule
移动到
base
的主包中,但它迫使我在项目中实现测试库,从我的角度来看,这不是一个好方法。

我不想为所有模块重复

MainCoroutineRule
,我想从公共源访问它。

任何方法将不胜感激。

android junit kotlin-coroutines android-testing
1个回答
1
投票

如果我将

MainCoroutineRule
移动到公共模块中的测试目录,假设
base
BlaViewModelTest
在测试运行时无法访问
MainCoroutineRule
,最终失败。编译时没有问题。

测试源在消费者模块中不可用。我不知道为什么它们在编译时可用以及为什么 IDE 不会抱怨它,但我确实经历过同样的事情。

要解决此问题,您可以创建一个单独的仅测试模块(例如

base-testing
test-utils
)。该规则应该是模块正常源的一部分(
src/main
not
src/test
)。然后您可以将该模块作为
testImplementation
包含在您的消费者模块中。

© www.soinside.com 2019 - 2024. All rights reserved.