Пусть функция suspend ничего не возвращает - PullRequest
1 голос
/ 27 января 2020

Рассмотрим этот класс:

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() еще не вернулся?

1 Ответ

1 голос
/ 28 января 2020

Опция 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!!)
...