我有一个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
,我想从公共源访问它。
任何方法都将受到赞赏。
1条答案
按热度按时间mw3dktmi1#
如果我将
MainCoroutineRule
移动到一个公共模块中的测试目录,比如说base
,BlaViewModelTest
在测试运行时无法访问MainCoroutineRule
,最后失败。编译时没有问题。测试源代码将无法在消费者模块中使用。我不知道为什么它们在编译时可用,为什么IDE没有抱怨它,但我肯定经历了同样的事情。
要解决这个问题,您可以创建一个单独的测试专用模块(例如:
base-testing
,test-utils
)。规则应该是模块正常源代码的一部分(src/main
,不是src/test
)。然后,您可以将该模块作为testImplementation
包含在消费者模块中。