Как проверить наблюдаемые ViewModel LiveData внутри моего теста? - PullRequest
0 голосов
/ 26 декабря 2018

В настоящее время я пытаюсь написать тест для своего класса ViewModel.Мне уже удалось написать несколько тестов для его обновлений LiveData и проверенного поведения.

Однако, когда я попытался протестировать метод с цепочечными методами и посмотреть, правильно ли обновились мои связанные LiveData, ничего не произошло.Тест выдает ошибку, в которой говорится, что во время теста не было ни одного вызова.

Ниже описано, как я пытался проверить объект LiveData

class WorkViewModelTest : AndroidTest() {
@Mock
private lateinit var sqlQueryUseCase: SqlQueryUseCase
private lateinit var workViewModel: WorkViewModel
val prefs = PreferencesHelper.defaultPrefs(context())
val resourceProvider = ResourceProvider(context())

@Before
fun setup() {
    workViewModel = WorkViewModel(sqlQueryUseCase, prefs, resourceProvider)
    workViewModel.toggleProductListState.observeForever {}
}

@Test
fun `When invalid barcode text given to function, it returns error message`() {
    //given
    val invalidString: String? = null
    val observer = mock<Observer<String>>()
    workViewModel.warningMessage.observeForever(observer)

    //when
    workViewModel.checkProductCode(invalidString)

    //then
    verify(observer).onChanged(resourceProvider.getStringFromResources(R.string.work_screen_empty_product_code_warning))
}

---> Это тест, который не прошел

@Test
fun `When user read a barcode and it is not found on remote with ERP System, we should move our state to error`() {
    //given
    val barcode = "123456789"
    val observer = mock<Observer<String>>()
    workViewModel.warningMessage.observeForever(observer)

    given {
        runBlocking { sqlQueryUseCase.run(any()) }
    }.willReturn(Either.Right(emptyList())

    //when
    runBlocking { workViewModel.checkProductCode(barcode) }
    //then
    verify(observer).onChanged(resourceProvider.getStringFromResources(R.string.work_screen_data_not_found_for_given_barcode_warning))
}

Вот мой класс ViewModel, который вызывает некоторые варианты использования и извлекает данные из удаленного соединения:

class WorkViewModel
@Inject constructor(
private val sqlQueryUseCase: SqlQueryUseCase,
private val prefs: SharedPreferences,
private val resourceProvider: ResourceProvider
) : BaseViewModel() {

val productListState: MutableLiveData<Boolean> = MutableLiveData()
val itemList: MutableLiveData<List<ItemDetailModel>> = MutableLiveData()
val warningMessage: MutableLiveData<String> = MutableLiveData()
val productInformation: MutableLiveData<String> = MutableLiveData()

val toggleProductListState = Transformations.map(itemList) {
    if (it.isEmpty()) {
        productListState.postValue(false)
    } else {
        productListState.postValue(true)
    }
}

fun initializeItemList(itemList: List<ItemDetailModel>) {
    this.itemList.postValue(itemList)
}

fun checkProductCode(productCode: String?) {
    if (productCode.isNullOrEmpty()) {
        warningMessage.postValue(resourceProvider.getStringFromResources(R.string.work_screen_empty_product_code_warning))
    } else {
        executeSqlQuery(productCode)
    }
}

private fun executeSqlQuery(productCode: String) {
    sqlQueryUseCase(
        SqlQueryUseCase.Params(
            String.createAuthToken(PreferencesHelper.getAuthorizationToken(prefs)),
            RequestBody.create(
                MediaType.parse("application/json"),
                QueryCreatorFactory.createQueryCreatorFromErpType(
                    prefs,
                    resourceProvider
                ).getProductInformationFromBarcodeQuery(productCode)!!.toByteArray(Charsets.UTF_8)
            )
        )
    ) {
        it.either(::handleErrorState, ::handleQueryResult)
    }
}

private fun handleQueryResult(resultData: List<Any>) {
    if (resultData.isNotEmpty()) {
        productInformation.postValue(resultData[0] as String)
    } else {
        warningMessage.postValue(resourceProvider.getStringFromResources(R.string.work_screen_data_not_found_for_given_barcode_warning))
    }
}

private fun handleErrorState(failure: Failure) {
    if (failure is Failure.ServerError)
        warningMessage.postValue(failure.errorMessage)
    else
        warningMessage.postValue("Some other failure")
}
}

То, чего я пытаюсь достичь, это всякий раз, когда пользователь пытается получить информацию оПродукт со штрих-кодом, который на самом деле не хранится в системе, мы получим пустой список в качестве ответа, и в этом случае ViewModel должен отправить предупреждающее сообщение через warningMessage LiveData.

Однако с тестом, который я написалЯ не вижу в моде отладки, что функция handleQueryResult вызывается вообще.Я борюсь с этой проблемой, и так как я немного новичок в Mockito, я не могу понять, что не так с моим тестом.Любая помощь приветствуется.Большое спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...