Рассмотрим этот класс:
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
, оно на самом деле не является, очевидно, ,
Когда мы работали с Rx Java, LoginInteractor
выглядел бы так:
interface LoginInteractor {
fun login(): Single<Boolean>
}
и в тесте мы могли бы сделать
given(interactor.login()).willReturn(Single.never())
проверить состояние ViewModel на момент входа в систему; как я могу задержать / не вернуть ничего из функции suspend
моего интерактора login()
, чтобы проверить состояние ViewModel, когда вызывается loginClicked()
, но interactor.login()
еще не вернулся?