junit 所有模块的通用协程规则- Android单元测试

643ylb08  于 2023-10-20  发布在  Android
关注(0)|答案(1)|浏览(125)

我有一个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 s提供Loopers,例如:

@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")
    }
}

我的问题是,我只能从BlaViewModelTest所在的同一个模块测试目录访问MainCoroutineRule
如果我将MainCoroutineRule移动到一个公共模块中的测试目录,比如说base,那么BlaViewModelTest在测试运行时无法访问MainCoroutineRule,最后失败。编译时没有问题。
我试图将MainCoroutineRule移动到base的主包中,但这迫使我在项目中实现测试库,从我的Angular 来看这不是一个好方法。
我不想为所有模块复制MainCoroutineRule,我想从公共源访问它。
任何方法都将受到赞赏。

mw3dktmi

mw3dktmi1#

如果我将MainCoroutineRule移动到一个公共模块中的测试目录,比如说baseBlaViewModelTest在测试运行时无法访问MainCoroutineRule,最后失败。编译时没有问题。
测试源代码将无法在消费者模块中使用。我不知道为什么它们在编译时可用,为什么IDE没有抱怨它,但我肯定经历了同样的事情。
要解决这个问题,您可以创建一个单独的测试专用模块(例如:base-testingtest-utils)。规则应该是模块正常源代码的一部分(src/main不是src/test)。然后,您可以将该模块作为testImplementation包含在消费者模块中。

相关问题