【发布时间】:2022-01-18 16:28:56
【问题描述】:
我有一个 ViewModel 类:
@HiltViewModel
class MyViewModel @Inject constructor(
private val repo: Repo,
) : ViewModel() {
val id = mutableStateOf(TextFieldValue())
fun init(token: String?) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
id.value = TextFieldValue(repo.getId(token))
}
}
}
}
我想为init函数写一个测试代码。
下面是我的测试代码:
@ExperimentalCoroutinesApi
@ExtendWith(InstantExecutorExtension::class, CoroutinesTestExtension::class)
class MyViewModelTest {
@get:Rule
var coroutineScope = CoroutinesTestExtension()
@Mock
private lateinit var repo: Repo
private lateinit var vm: MyViewModel
@BeforeEach
fun setup() {
MockitoAnnotations.openMocks(this)
vm = MyViewModel(repo)
}
@Nested
@DisplayName("init() test")
inner class InitTest {
private val token = "test-token"
@Test
fun initTest() = runTest {
val id = "test-id"
`when`(repo.getId(token))
.thenReturn(id)
vm.init(token)
advanceUntilIdle()
assertEquals(id, vm.id.value.text)
}
}
如果我运行此测试代码,它会失败并显示以下消息:
expected:<[test-id]> but was:<[]>
Expected :test-id
Actual :
我发现了一些东西......
首先,如果我删除withContext(Dispatchers.IO) { } 行,测试通过!
但repo.getId(token) 应该在后台线程上运行。
其次,如果我将id 的类型从MutableStateOf 更改为MutableLiveData,它可以正常工作。
但是id 正在View/Fragment 上使用,例如:
@Composable
fun MyTextInput() {
OutlinedTextField(
value = viewModel.id.value,
onValueChange = { viewModel.id.value = it },
)
}
所以我无法改变它。
我该如何解决这个问题?
【问题讨论】:
标签: android kotlin android-jetpack-compose junit5 coroutine