我有一个
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
,我想从公共源访问它。
任何方法将不胜感激。
如果我将
移动到公共模块中的测试目录,假设MainCoroutineRule
,base
在测试运行时无法访问BlaViewModelTest
,最终失败。编译时没有问题。MainCoroutineRule
测试源在消费者模块中不可用。我不知道为什么它们在编译时可用以及为什么 IDE 不会抱怨它,但我确实经历过同样的事情。
要解决此问题,您可以创建一个单独的仅测试模块(例如
base-testing
、test-utils
)。该规则应该是模块正常源的一部分(src/main
,notsrc/test
)。然后您可以将该模块作为 testImplementation
包含在您的消费者模块中。