使用实时数据,协程(Kotlin)测试视图模型

时间:2019-12-20 09:44:14

标签: kotlin retrofit2 viewmodel android-livedata coroutine

几天来我一直在尝试测试我的视图模型,但没有成功。

这是我的视图模型:

class AdvertViewModel : ViewModel() {

    private val parentJob = Job()

    private val coroutineContext: CoroutineContext
        get() = parentJob + Dispatchers.Default

    private val scope = CoroutineScope(coroutineContext)

    private val repository : AdvertRepository = AdvertRepository(ApiFactory.Apifactory.advertService)

    val advertContactLiveData = MutableLiveData<String>()

    fun fetchRequestContact(requestContact: RequestContact) {
        scope.launch {
            val advertContact = repository.requestContact(requestContact)
            advertContactLiveData.postValue(advertContact)
        }
    }
}

这是我的存储库:

class AdvertRepository (private val api : AdvertService) : BaseRepository() {

    suspend fun requestContact(requestContact: RequestContact) : String? {

        val advertResponse = safeApiCall(
            call = {api.requestContact(requestContact).await()},
            errorMessage = "Error Request Contact"
        )

        return advertResponse
    }
}

这是我的视图模型测试:

@RunWith(JUnit4::class)
class AdvertViewModelTest {
    private val goodContact = RequestContact(...)

    private lateinit var advertViewModel: AdvertViewModel

    private var observer: Observer<String> = mock()

    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

    @Before
    fun setUp() {
        advertViewModel = AdvertViewModel()
        advertViewModel.advertContactLiveData.observeForever(observer)
    }

    @Test
    fun fetchRequestContact_goodResponse() {
        advertViewModel.fetchRequestContact(goodContact)

        val captor = ArgumentCaptor.forClass(String::class.java)

        captor.run {
            verify(observer, times(1)).onChanged(capture())
            assertEquals("someValue", value)
        }
    }
}

mock()方法:

inline fun <reified T> mock(): T = Mockito.mock(T::class.java)

我收到此错误:

  

希望但不被调用:observer.onChanged();   -> com.vizzit.AdvertViewModelTest.fetchRequestContact_goodResponse(AdvertViewModelTest.kt:52)   实际上,与该模拟游戏的互动为零。

我不知道如何检索查询结果。

1 个答案:

答案 0 :(得分:1)

您需要编写OneTimeObserver来观察来自ViewModel的实时数据

class OneTimeObserver<T>(private val handler: (T) -> Unit) : Observer<T>, LifecycleOwner {
    private val lifecycle = LifecycleRegistry(this)

    init {
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }

    override fun getLifecycle(): Lifecycle = lifecycle

    override fun onChanged(t: T) {
        handler(t)
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    }
}

之后,您可以编写扩展功能:

fun <T> LiveData<T>.observeOnce(onChangeHandler: (T) -> Unit) {
    val observer = OneTimeObserver(handler = onChangeHandler)
    observe(observer, observer)
}

比起您在执行方法时(何时)执行操作时,您可以检查项目中的this ViewModel class类,以检查LiveData的情况。

对于您的错误,它只是说onChanged()方法从未被调用。