Koin测试clarifyMock无法使用倍数声明

问题描述

我试图声明两个模拟,但是我遇到了java.lang.classCastException。

我正在尝试测试MainActivity(具有Mainviewmodel),因此我需要模拟Mainviewmodel。 问题是,当我启动MainActivity进行测试时,由于我正在使用导航组件,并且我的MainActivity包含NavHostFragment并认启动SplashFragment(具有Splashviewmodel),因此会注入SplashFragment。

摘要:应用程序-> MainActivity(尝试测试MainActivity中的一些常见组件)->飞溅片段

private val testViewState = MediatorLiveData<MainViewState>()
private val testSplashViewState = MediatorLiveData<SplashViewState>()

@Rule
@JvmField
var mockSplashviewmodelRule = MockProviderRule.create {
    mock(Splashviewmodel::class.java)
}

@Rule
@JvmField
var mockviewmodelRule = MockProviderRule.create {
    mock(Mainviewmodel::class.java)
}


private fun launchMainActivity() {
    declareMock<Splashviewmodel> {
        given(viewState).willReturn(testSplashViewState)
    }

    declareMock<Mainviewmodel> {
        given(viewState).willReturn(testViewState)
    }
    activityScenarioRule.scenario
}

我收到此错误 java.lang.classCastException:Splashviewmodel无法转换为Mainviewmodel

如果我没有声明Splashviewmodel,我将得到: java.lang.RuntimeException:org.koin.core.error.NoBeanDefFoundException:未找到类“ Splashviewmodel”的定义。检查您的定义!

有什么想法吗?

解决方法

我以这种方式解决了

private val testSplashViewState = MediatorLiveData<SplashViewState>()
private val testViewState = MediatorLiveData<MainViewState>()

@Mock
private lateinit var mainViewModel: MainViewModel

@Mock
private lateinit var splashViewModel: SplashViewModel

@Rule
@JvmField
var activityScenarioRule = LateInitActivityScenarioRule(MainActivity::class.java,false)

val module = module(createdAtStart = true,override = true) {
    viewModel { splashViewModel }
    viewModel { mainViewModel }
}

@Before
fun setupMainActivityTest() {
    loadKoinModules(module)
}

@After
fun afterMainActivityTest() {
    unloadKoinModules(module)
}

private fun launchMainActivity() {
    testSplashViewState.value = SplashViewState()
    whenever(splashViewModel.viewState).thenReturn(testSplashViewState)

    testViewState.value = MainViewState()
    whenever(mainViewModel.viewState).thenReturn(testViewState)
    activityScenarioRule.scenario
}