简体   繁体   English

协程单元测试kocklinx.coroutines.CoroutineContextKt.newCoroutineContext中的Mockk java.lang.AbstractMethodError

[英]Coroutines Unit test Mockk java.lang.AbstractMethodError at kotlinx.coroutines.CoroutineContextKt.newCoroutineContext

I want to unit test a method in viewmodal but everytime i failed, and had gone through many of the websites and stack answers but none of them helped out. 我想在viewmodal中对一个方法进行单元测试,但每次我都失败了,并且经历了很多网站和堆栈的答案,但没有一个帮助过。 I just wanted to test a method in my viewmodal that is loadWeatherForeCast 我只是想在我的viewmodal中测试一个loadWeatherForeCast的方法

I had gone through the following links, Error calling Dispatchers.setMain() in unit test 我已经通过以下链接, 错误在单元测试中调用Dispatchers.setMain()

https://android.jlelse.eu/mastering-coroutines-android-unit-tests-8bc0d082bf15 https://android.jlelse.eu/mastering-coroutines-android-unit-tests-8bc0d082bf15

https://proandroiddev.com/mocking-coroutines-7024073a8c09 https://proandroiddev.com/mocking-coroutines-7024073a8c09

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.verify
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import go_jek.domain.entities.LocationTemperature
import go_jek.domain.interactor.Result
import go_jek.domain.interactor.weatherUseCase.WeatherParam
import go_jek.domain.interactor.weatherUseCase.WeatherUseCase
import go_jek.domain.repository.ApiDataSource
import go_jek.utility.dateUtils.DateUtils

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class WeatherViewModelTest {
@get:Rule
val rule = InstantTaskExecutorRule()

@MockK
lateinit var apiDataSource: ApiDataSource       //Interface

@MockK
lateinit var dateUtilImpl: DateUtils                //Interface

@MockK
lateinit var weatherParam: WeatherParam

@MockK
lateinit var locationTemperatureOutput: LocationTemperature

private lateinit var weatherUseCase: WeatherUseCase
private lateinit var weatherViewModel: WeatherViewModel

@BeforeAll
fun setup() {
    MockKAnnotations.init(this)

    weatherUseCase = WeatherUseCase(apiDataSource)
    weatherViewModel = WeatherViewModel(weatherUseCase, dateUtilImpl, Dispatchers.Unconfined)
}

@Test
fun check() = runBlocking {
    every {
        weatherUseCase.execute(any(), any(), any())
    } answers {
        thirdArg<(Result<LocationTemperature>) -> Unit>().invoke(Result.Success(locationTemperatureOutput))
    }

    weatherViewModel.loadWeatherForeCast(32.45, 72.452)

    verify(atLeast = 1) {
        apiDataSource.getWeatherInfo(weatherParam)
    }
}
}


interface ApiDataSource {
fun getWeatherInfo(weatherParam: WeatherParam):   Result<LocationTemperature>
}


 class WeatherUseCase(var apiDataSource: ApiDataSource) :   UseCase<LocationTemperature, WeatherParam>() {
override suspend fun run(params: WeatherParam): Result<LocationTemperature> = apiDataSource.getWeatherInfo(params)

} }

 class WeatherParam(
val apiKey: String = BuildConfig.appixu_secretkey,
val location: String
  ) : UseCase.NoParams()


 class LocationTemperature(val location: Location, val current: Current, val forecast: Forecast) : Parcelable


 class WeatherViewModel (val weatherUseCase: WeatherUseCase,
                    val dateUtilImpl: DateUtils,
                    val uiContext: CoroutineContext = Dispatchers.Main) : ViewModel(), CoroutineScope {

private val job: Job

private val _locationLiveData = MutableLiveData<LocationTemperature>()
val locationLiveData: LiveData<LocationTemperature>

private val _error: MutableLiveData<String> = MutableLiveData()
var error: LiveData<String> = _error

private val loadingState = MutableLiveData<Boolean>()
val loadingLiveData = loadingState

override val coroutineContext: CoroutineContext
    get() = uiContext + job

init {
    job = Job()

    locationLiveData = Transformations.map(_locationLiveData) {
        it.apply {
            forecast.forecastday.forEach {
                it.dayOfWeek = dateUtilImpl.format(it.date, DateUtils.FOR_YYYY_H_MM_H_DD, FULL_DAY)
            }
        }
    }
}

fun handleError(error: Exception) {
    loadingState.value = false
    _error.value = error.localizedMessage
}

fun loadWeatherForeCast(latitude: Double, longitude: Double) {
    val weatherParam = WeatherParam(location = String.format(Locale.getDefault(), "%1f, %2f",
        latitude, longitude))

    weatherUseCase.execute(this, weatherParam)
    {
        when (it) {
            is Result.Success -> {
                loadingState.value = false
                _locationLiveData.value = it.data
            }
            is Result.Error -> {
                handleError(it.exception)
            }
        }
    }
}

override fun onCleared() {
    job.cancel()
    super.onCleared()
}

} }

To use mockK with coroutines you need to use the new "coEvery" and "coVerify" functions and it will work better : 要使用带有协同程序的mockK,您需要使用新的“coEvery”和“coVerify”函数,它将更好地工作:

https://mockk.io/#coroutines https://mockk.io/#coroutines

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 MockK 测试 LiveData 和协程 - Test LiveData and Coroutines using MockK 致命异常:java.lang.NoClassDefFoundError:kotlinx.coroutines.CoroutineExceptionHandlerImplKt - Fatal Exception: java.lang.NoClassDefFoundError: kotlinx.coroutines.CoroutineExceptionHandlerImplKt kotlinx.coroutines.test 最新的 API 用法 - kotlinx.coroutines.test the latest API usage “ PG”类抛出java.lang.AbstractMethodError - “PG” class throwing java.lang.AbstractMethodError java.lang.AbstractMethodError: 抽象方法未实现 - java.lang.AbstractMethodError: abstract method not implemented java.lang.ClassCastException:kotlinx.coroutines.CompletableDeferredImpl 无法转换为 java.util.List? - java.lang.ClassCastException: kotlinx.coroutines.CompletableDeferredImpl cannot be cast to java.util.List? Android java.lang.AbstractMethodError on requestLocationUpdates - Android java.lang.AbstractMethodError on requestLocationUpdates AWS:身份验证处理程序java.lang.AbstractMethodError: - AWS: Authentication Handler java.lang.AbstractMethodError: 如何修复android中的java.lang.AbstractMethodError? - How to fix java.lang.AbstractMethodError in android? java.lang.IllegalArgumentException:无法为kotlinx.coroutines.Deferred创建调用适配器 - java.lang.IllegalArgumentException: Unable to create call adapter for kotlinx.coroutines.Deferred
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM