微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Android中使用流程协程Kotlin的单元测试存储库

如何解决在Android中使用流程协程Kotlin的单元测试存储库

我想为我的repository编写单元测试。 repository方法返回flow。首先,addDiaryRate方法的加载状态为emit,然后从网络返回数据。我想验证addDiaryRate方法是否先加载然后进行数据响应。我写了这个测试,但是我的测试失败了。错误提示期望值和实际值不相等。

java.lang.AssertionError: 预期:是 但是:是 预期:is 实际:

我使用Codelab和Google示例的示例代码。 这是MainRepository

   class MainRepositoryImp constructor(
    private val apiService: MainApiService,private val suggestionModelDao: SuggestionModelDao,private val userDao: UserDao,private val babyDao: BabyDao,private val diaryHotDao: DiaryHotDao,private val diaryUserDao: DiaryUserDao,private val hashTagModelDao: HashTagModelDao,private val diaryTopDao: DiaryTopDao,private val diaryResultSearchDao: DiaryResultSearchDao,private val rateModelDao: RateModelDao,private val medalDao: MedalDao,private val blogModelDao: BlogModelDao,private val seenDiaryDao: SeenDiaryDao,private val rateModelAppDao: RateModelAppDao,private val diarySavedDao: DiarySavedDao,private val diaryAnotherUserDao: DiaryAnotherUserDao,private val anotherUserInfoDao: AnotherUserInfoDao,private val followDao: FollowDao,private val suggestProductDao: SuggestProductDao,private val blogSuggestWithHashTagDao: BlogSuggestWithHashTagDao,private val suggestHashtagDao: SuggestHashtagDao,private val sessionManager: SessionManager
) : MainRepository {
 override fun addratetoDiary(rate: String,diaryId: String): Flow<DataState<RateResponse>> =
        flow {
            emit(DataState.loading(true))

            val apiResult = safeApiCall(
                sessionManager.isConnectedToTheInternet()
            ) {
                apiService.addrate(
                    diaryId,AddrateRequest(rate),sessionManager.cachedAccesstoken.value ?: ""
                )
            }

            emit(
                object : ApiResponseHandler<RateResponse,RateResponse>(
                    response = apiResult
                ) {
                    override suspend fun handleSuccess(resultObj: RateResponse): DataState<RateResponse> {
                        safeCacheCall {
                            diaryHotDao.updaterateStateDiary(
                                resultObj.data.symbolPath ?: "",diaryId,resultObj.data.rate
                            )
                            var countRate = 0
                            var userId = 0
                            userDao.fetchUser()?.let {
                                countRate = it.countRates + 1
                                userId = it.id
                            }
                            userDao.updateCountRate(countRate,userId)
                        }
                        return DataState.data(resultObj)
                    }

                }.getResult()
            )
        }
}

这是我的考试班:

@ExperimentalCoroutinesApi
@RunWith(RobolectricTestRunner::class)
@InternalCoroutinesApi
class MainRepositoryTest
{
    private lateinit var repository: MainRepository
    private var apiService = FakeUnitTestApiService()

    private lateinit var suggestionModelDao: SuggestionModelDao
    private lateinit var userDao: UserDao
    private lateinit var babyDao: BabyDao
    private lateinit var diaryHotDao: DiaryHotDao
    private lateinit var diaryUserDao: DiaryUserDao
    private lateinit var hashTagModelDao: HashTagModelDao
    private lateinit var diaryTopDao: DiaryTopDao
    private lateinit var diaryResultSearchDao: DiaryResultSearchDao
    private lateinit var rateModelDao: RateModelDao
    private lateinit var medalDao: MedalDao
    private lateinit var blogModelDao: BlogModelDao
    private lateinit var seenDiaryDao: SeenDiaryDao
    private lateinit var rateModelAppDao: RateModelAppDao
    private lateinit var diarySavedDao: DiarySavedDao
    private lateinit var diaryAnotherUserDao: DiaryAnotherUserDao
    private lateinit var anotherUserInfoDao: AnotherUserInfoDao
    private lateinit var followDao: FollowDao
    private lateinit var suggestProductDao: SuggestProductDao
    private lateinit var blogSuggestWithHashTagDao: BlogSuggestWithHashTagDao
    private lateinit var suggestHashtagDao: SuggestHashtagDao


    private lateinit var sessionManager: SessionManager
    private lateinit var db: AppDatabase

    private lateinit var prefManager: PrefManager

    @Rule
    @JvmField
    val instantExecutorRule = InstantTaskExecutorRule()


    @ExperimentalCoroutinesApi
    @get:Rule
    var mainCoroutineRule = MainCoroutineRule()

    @Before
    fun init() {
      val app = ApplicationProvider.getApplicationContext<Application>()

        prefManager=PrefManager(app)
        db = Room.inMemoryDatabaseBuilder(
            app,AppDatabase::class.java
        ).allowMainThreadQueries().build()
        initDao()
        sessionManager = SessionManager(
            app,userDao,babyDao,diaryHotDao,diaryTopDao,diaryUserDao,hashTagModelDao,medalDao,suggestionModelDao,diaryResultSearchDao,rateModelDao,blogModelDao,seenDiaryDao,rateModelAppDao,diarySavedDao,diaryAnotherUserDao,anotherUserInfoDao,followDao,suggestProductDao,blogSuggestWithHashTagDao,suggestHashtagDao,prefManager
        )
  
        repository = MainRepositoryImp(
            apiService,sessionManager
        )
    }

    private fun initDao() {
        suggestionModelDao = db.getSuggestionModelDao()
        userDao = db.getUserDao()
        babyDao = db.getBabyDao()
        diaryHotDao = db.getDiaryHotDao()
        diaryUserDao = db.getDiaryUserDao()
        hashTagModelDao = db.getHashTagModelDao()
        diaryTopDao = db.getDiaryTopDao()
        diaryResultSearchDao = db.getDiaryResultSearchDao()
        rateModelDao = db.getRateModelDao()
        medalDao = db.getMedalDao()
        blogModelDao = db.getBlogModelDao()
        seenDiaryDao = db.getSeenDiaryDao()
        rateModelAppDao = db.getRateModelAppDao()
        diarySavedDao = db.getDiarySavedDao()
        diaryAnotherUserDao = db.getDiaryAnotherUserDao()
        anotherUserInfoDao = db.getAnotherUserInfoDao()
        followDao = db.getFollowDao()
        suggestProductDao = db.getBlogProductDao()
        blogSuggestWithHashTagDao = db.getBlogSuggestWithHashTagDao()
        suggestHashtagDao = db.getBlogSuggestDao()
    }


    @Test
    fun addratetest() = mainCoroutineRule.runBlockingTest{
        /** GIVEN  **/
        val response = RateResponse(
            RateModel(
                id = "1",symbolPath = "symbol path",rate = 3,point = 2f,diaryId = "333",count = "34"
            )
        )

        /** WHEN **/
        repository.addratetoDiary("2","333").collect{

            assertthat(it,`is`(DataState.loading<RateResponse>(true)))

            assertthat(it,`is`(DataState.data<RateResponse>(response)))
        }
    }

解决方法

最后我找到了解决方案。 1-我使用runBlocking而不是mainCoroutineRule.runBlockingTest。 2-为了验证flow的所有发射值,我们可以使用toList()方法。 这是我的fakeApiService:

    open class FakeUnitTestApiService(
    var addRateImpl: suspend (
        id: String,addRateRequest: AddRateRequest,token: String
    ) -> GenericApiResponse<RateResponse> = notImplemented2()
) : MainApiService {
    companion object {
        private fun <T,R> notImplemented1(): suspend (t: T) -> R {
            return { t: T ->
                TODO("")
            }
        }

        private fun <T,R> notImplemented2(): suspend (t: T,s: T,l: T) -> R {
            return { t: T,l: T ->
                TODO("")
            }
        }
    }

    override suspend fun addRate(
        id: String,token: String
    ): GenericApiResponse<RateResponse> = addRateImpl(id,addRateRequest,token)
}

这是我的测试功能:

@Test
fun addRateTest() = runBlocking{
    /** GIVEN  **/
    val response = RateResponse(
        RateModel(
            id = "1",symbolPath = "symbol path",rate = 3,point = 2f,diaryId = "333",count = "34"
        )
    )

    /** WHEN **/
    apiService.addRateImpl = { s: String,s1: String ->
        GenericApiResponse.create(Response.success(response))
    }
    val list=repository.addRateToDiary("2","333").toList()

    /**THEN**/
    assertThat(list.first().loading.isLoading,`is`(true))
    assertThat(list.last().data?.peekContent(),`is`(response))
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。