koin = "3.6.0-Beta4"
koinComposeMultiplatform = "1.2.0-Beta4"
truth = "1.0.1"
mockito = "2.21.0"
mockk = "1.13.2"
kotinx="1.7.0"
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koinComposeMultiplatform" }
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koinComposeMultiplatform" }
kotlinx-coroutines={module = "org.jetbrains.kotlinx:kotlinx-coroutines-test",version.ref="kotinx"}
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" }
koin-test-junit4 = { module = "io.insert-koin:koin-test-junit4", version.ref = "koin" }
google-truth = { module = "com.google.truth:truth", version.ref = "truth" }
mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
添加依赖
val desktopTest by getting
desktopTest.dependencies {
implementation(libs.kotlin.test)
implementation(libs.koin.test)
implementation(libs.koin.test.junit4)
implementation(libs.kotlinx.coroutines)
implementation(libs.google.truth)
implementation(libs.mockito.core)
implementation(libs.mockk)
}
以登录测试为例
测试class要继承 KoinTest
class LoginByPwdOrCardViewModelTest : KoinTest {}
在测试开始时,对koin进行初始化
@BeforeTest
fun setUp() {
initTestKoin()
}
InitKoin.kt
fun initTestKoin(config: KoinAppDeclaration? = null) {
startKoin {
config?.invoke(this)
modules( testModule, viewModelModule)
}
}
Modules.kt
val testModule = module {
singleOf(::TestDeskTopRepository).bind<DeskTopRepository>()
}
val viewModelModule= module {
// viewModelOf(::LoginByPwdOrCardViewModel)\
factory { LoginByPwdOrCardViewModel(get()) } //每次都是重新生成
}
桌面开发的viewmodel 和Android的viewmodel 创建方式不一样,Android有屏幕旋转,生命周期等感知
结束清理工作
@AfterTest
fun tearUp() {
stopKoin()
}
这样就可以通过注入的方式初始化viewmode
private val viewModel by inject<LoginByPwdOrCardViewModel>()
做几个测试示例
@Test
fun testNeedAdminNormalUser_emitError() = runTest {
viewModel.needAdmin.value = true//需要管理员权限
viewModel.accountInputState.value = "linlian"
viewModel.passwordInputState.value = "2"
viewModel.loginByAccount()
val event = viewModel.error.first() //shareflow 会阻塞等待
assertThat(event.getContentIfNotHandled()?.status).isEqualTo(Status.ERROR)
}
@Test
fun testLoginValidUser_emitError() = runTest {
viewModel.accountInputState.value = "Invalid"
viewModel.passwordInputState.value = "2"
viewModel.loginByAccount()
val event = viewModel.error.first() //shareflow 会阻塞等待
assertThat(event.getContentIfNotHandled()?.status).isEqualTo(Status.ERROR)
}
@Test
fun testNeedAdminAdminUser_userInfoNotNull() = runTest {
viewModel.needAdmin.value = true//需要管理员权限
viewModel.accountInputState.value = "Admin"
viewModel.passwordInputState.value = "2"
val job = viewModel.loginByAccount()
job.join()
val userInfo = LoginUserUtils.userInfoFlow.first() //stateflow不会阻塞等待
assertThat(userInfo).isNotNull()
}