如何在查看模型和存储库 return 实时数据时创建单元测试 Android

How to create unit test when u'r view model & repository return live data for Android

我已经为我的视图模型创建了一些单元测试。但是当我 println() 结果总是 return 状态加载..我试图阅读一些文章和其他源代码中的 cek 但我仍然没有找到答案。

这是我来自 ViewModel 的代码:

class PredefineViewModel() : ViewModel() {

private var predefineRepository: PredefineRepository? = PredefineRepository()

private val _predefined = MutableLiveData<String>()

val predefined: LiveData<Resource<Payload<Predefine>>> =
        Transformations.switchMap(_predefined) {
            predefineRepository?.predefine()
        }

fun predefined() {
        _predefined.value = "predefined".random().toString()
    }

}

这是我的存储库

class PredefineRepository()  {

private val api: PredefineApi? = PredefineApi.init()

fun predefine(): BaseMutableLiveData<Predefine> {
        val predefine: BaseMutableLiveData<Predefine> = BaseMutableLiveData()

        api?.let { api ->
            predefine.isLoading()

            api.predefined().observe()?.subscribe({ response ->
                response?.let { resource ->
                    predefine.isSuccess(resource)
                }
            }, { error ->
                predefine.isError(error)
            })
        }


        return predefine
    }

}

这是我的资源状态:

data class Resource<T>(var status: Status? = null, var meta: Meta? = null, var payload: T? =null) {
    companion object {
        fun <T> success(data: T?, meta: Meta): Resource<T> {
            return Resource(Status.SUCCESS, meta, data)
        }

        fun <T> error(data: T?, meta: Meta): Resource<T> {
            return Resource(Status.ERROR, meta, data)
        }

        fun <T> loading(data: T?, meta: Meta): Resource<T> {
            return Resource(Status.LOADING, null, null)
        }
    }
}

更新测试CLASS 而且,这是我尝试从我的实时数据视图模型打印和检查值的示例:

class PredefineViewModelTest {

    @get:Rule
    val taskExecutorRule = InstantTaskExecutorRule()

    private lateinit var viewModel: PredefineViewModel
    private lateinit var repository: PredefineRepository
    private lateinit var api: Api

    @Before
    fun setUp() {
        api = Networks().bridge().create(Api::class.java)
        repository = PredefineRepository()
        viewModel = PredefineViewModel()
    }

    @Test
    fun test_predefined(){
        val data = BaseMutableLiveData<Predefine>()

        val result = api.predefined()
        result.test().await().assertComplete()
        result.subscribe {
            data.isSuccess(it)
        }

        `when`(repository.predefine()).thenReturn(data)

        viewModel.predefined()
        viewModel.predefined.observeForever {
            println("value: $it")
            println("data: ${data.value}")
        }
    }

}

更新日志结果 为什么我预定义的结果总是:

value: Resource(status=LOADING, meta=null, payload=null, errorData=[])

data: Resource(status=SUCCESS, meta=Meta(code=200, message=success, error=null), payload= Data(code=200, message=success, errorDara =[])

谢谢..

我看不到你的 API 模拟。您的初始状态正在加载到 LiveData 中。

{ response ->
            response?.let { resource ->
                predefine.isSuccess(resource)
            }

块在测试期间未执行。

您需要模拟您的 API 响应。单元测试不会 运行 你 API 实际上你必须嘲笑它​​。请查看随附的代码片段,它将为您提供实现该目标的基本思路。

视图模型:

class MainViewModel(val repository: Repository) : ViewModel() {

    fun fetchData(): LiveData<Boolean> {
        return Transformations.map(repository.getData()) {
            if (it.status == 200) {
                true
            } else {
                false
            }
        }
    }
}

回购:

open class Repository {

    open fun getData() : LiveData<MainModel> {
        return MutableLiveData(MainModel(10, 200))
    }
}

测试Class:

@RunWith(MockitoJUnitRunner::class)
 class MainViewModelTest {

    lateinit var mainModel: MainViewModel

    @Rule
    @JvmField
    var rule: TestRule = InstantTaskExecutorRule()

    @Mock
    lateinit var repo: Repository

    init {
        MockitoAnnotations.initMocks(this)
    }

    @Before
    fun setup() {
        mainModel = MainViewModel(repo)
    }

    @Test
    fun fetchData_success() {
             val mainModelData = MainModel(10, 200)
        `when`(repo.getData()).thenReturn(MutableLiveData(mainModelData))


        mainModel.fetchData().observeForever {
            Assert.assertTrue(it)
        }
    }

    @Test
    fun fetchData_failure() {
        val mainModelData = MainModel(10, 404)
        `when`(repo.getData()).thenReturn(MutableLiveData(mainModelData))

        mainModel.fetchData().observeForever {
            Assert.assertFalse(it)
        }
    }

}