如何在测试中验证观察到的ViewModel LiveData?

时间:2018-12-26 08:51:52

标签: android testing kotlin mockito

我目前正在尝试为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发出警告消息。

但是,在编写的测试中,我在调试mod中根本看不到“ handleQueryResult”函数已被调用。我正在为这个问题而苦苦挣扎,而且由于我对Mockito有点陌生,所以我无法理解我的测试出了什么问题。欢迎任何帮助。非常感谢。

0 个答案:

没有答案