考虑此类:
class TestViewModel(private val interactor: LoginInteractor) : ViewModel() {
private val _loading = MutableLiveData<Boolean>().apply { value = false }
val loading: LiveData<Boolean> = _loading
fun loginClicked() {
viewModelScope.launch {
_loading.value = true
val isLoggedIn = interactor.login()
_loading.value = false
}
}
}
interface LoginInteractor {
suspend fun login(): Boolean
}
和测试:
class TestViewModelTest {
@Rule
@JvmField
var rule = InstantTaskExecutorRule()
@Mock
private lateinit var interactor: LoginInteractor
@InjectMocks
private lateinit var tested: TestViewModel
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
Dispatchers.setMain(TestCoroutineDispatcher())
}
@Test
fun `should set loading to true while loading`() = runBlockingTest {
given(interactor.login()).willReturn(true)
tested.loginClicked()
Assert.assertTrue(tested.loading.value!!)
}
}
断言
loading
的值是true
时,显然不是。当我们使用RxJava时,
LoginInteractor
看起来像:interface LoginInteractor {
fun login(): Single<Boolean>
}
在测试中,我们可以做到
given(interactor.login()).willReturn(Single.never())
在登录时测试ViewModel的状态;我如何才能延迟/不返回我的交互器的
suspend
函数login()
的任何内容,以在调用loginClicked()
但interactor.login()
尚未返回时测试ViewModel的状态?
最佳答案
选项1:
为了保证您的状态已更改,您可以订阅加载状态更改:
@Test
fun `should set loading to true while loading`() = runBlockingTest {
given(interactor.login()).willReturn(true)
var invocationCounter = 0
tested.loading.observerForever { loading ->
assertEquals(invocationCounter == 0, loading)
invocationCounter++
}
tested.loginClicked()
Assert.assertTrue(tested.loading.value!!)
}
选项2:
```
given(interactor.login()).willAnswer {
assertTrue(tested.loading.value)
true
}
tested.loginClicked()
Assert.assertFalse(tested.loading.value!!)
关于android - 让暂停功能不返回任何东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59935468/