I want to write unit test for my repository
. The repository
's methods return flow
. The addDiaryRate
method first of all emit
loading state then return data from network. I want to verify that addDiaryRate
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.
java.lang.AssertionError: Expected: is <DataState(error=null, loading=Loading(isLoading=true), data=null)> but: was <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))> Expected :is <DataState(error=null, loading=Loading(isLoading=true), data=null)> Actual :<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))>
I use sample code of codelab and google samples.
This is 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()
)
}
}
This is my test class:
@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,
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 = "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)))
}
}
Finally I find the solution.
I use
runBlocking
instead of usingmainCoroutineRule.runBlockingTest
.For verify all of emitted value of
flow
,We could usetoList()
method. This is my fakeApiService:And This is my test function: