title: unit testing repository that use flow coroutine kotlin in android
body: <p>I want to write unit test for my <code>repository</code>. The <code>repository</code>'s methods return <code>flow</code>. The <code>addDiaryRate</code> method first of all <code>emit</code> loading state then return data from network. I want to verify that <code>addDiaryRate</code> method emit loading then data response. I write this test but my test failed.The error say expected and actual isn't same while they are equal.</p>
  <blockquote>
  <p>java.lang.AssertionError:
  Expected: is &lt;DataState(error=null, loading=Loading(isLoading=true), data=null)&gt;
  but: was &lt;DataState(error=null, loading=Loading(isLoading=false), data=Event(content=RateResponse(data=RateModel(id=1, symbolPath=symbol path, rate=3, point=2.0, diaryId=333, count=34)), hasBeenHandled=false))&gt;
  Expected :is &lt;DataState(error=null, loading=Loading(isLoading=true), data=null)&gt;
  Actual   :&lt;DataState(error=null, loading=Loading(isLoading=false), data=Event(content=RateResponse(data=RateModel(id=1, symbolPath=symbol path, rate=3, point=2.0, diaryId=333, count=34)), hasBeenHandled=false))&gt;</p>
  </blockquote>
  <p>I use sample code of codelab and google samples.
  This is <code>MainRepository</code>:</p>
  <pre><code>   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&lt;DataState&lt;RateResponse&gt;&gt; =
          flow {
              emit(DataState.loading(true))
  
              val apiResult = safeApiCall(
                  sessionManager.isConnectedToTheInternet()
              ) {
                  apiService.addRate(
                      diaryId,
                      AddRateRequest(rate),
                      sessionManager.cachedAccessToken.value ?: &quot;&quot;
                  )
              }
  
              emit(
                  object : ApiResponseHandler&lt;RateResponse, RateResponse&gt;(
                      response = apiResult
                  ) {
                      override suspend fun handleSuccess(resultObj: RateResponse): DataState&lt;RateResponse&gt; {
                          safeCacheCall {
                              diaryHotDao.updateRateStateDiary(
                                  resultObj.data.symbolPath ?: &quot;&quot;,
                                  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()
              )
          }
  }
  </code></pre>
  <p>This is my test class:</p>
  <pre><code>@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&lt;Application&gt;()
  
          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,
              suggestionModelDao,
              userDao,
              babyDao,
              diaryHotDao,
              diaryUserDao,
              hashTagModelDao,
              diaryTopDao,
              diaryResultSearchDao,
              rateModelDao,
              medalDao,
              blogModelDao,
              seenDiaryDao,
              rateModelAppDao,
              diarySavedDao,
              diaryAnotherUserDao,
              anotherUserInfoDao,
              followDao,
              suggestProductDao,
              blogSuggestWithHashTagDao,
              suggestHashtagDao,
              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 = &quot;1&quot;,
                  symbolPath = &quot;symbol path&quot;,
                  rate = 3,
                  point = 2f,
                  diaryId = &quot;333&quot;,
                  count = &quot;34&quot;
              )
          )
  
          /** WHEN **/
          repository.addRateToDiary(&quot;2&quot;,&quot;333&quot;).collect{
  
              assertThat(it, `is`(DataState.loading&lt;RateResponse&gt;(true)))
  
              assertThat(it,`is`(DataState.data&lt;RateResponse&gt;(response)))
          }
      }
  </code></pre>