【发布时间】:2020-10-19 12:34:50
【问题描述】:
我想为我的repository 编写单元测试。 repository 的方法返回 flow。 addDiaryRate 方法首先 emit 加载状态然后从网络返回数据。我想验证addDiaryRate 方法发出加载然后数据响应。我写了这个测试,但我的测试失败了。错误说预期和实际是不一样的,而它们是相等的。
java.lang.AssertionError: 预期:是
但是:是 预期:是 实际:
我使用 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,
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)))
}
}
【问题讨论】:
标签: android unit-testing kotlin-coroutines flow