#android #kotlin #mockk
#Android #kotlin #mockk
Вопрос:
Я пытаюсь протестировать свою модель представления с помощью библиотеки mockK. но я не могу понять, как это сделать. Это мой класс. У меня есть вариант использования и репозиторий:
@ExperimentalCoroutinesApi
class MainViewModelTest {
private val getRecentPhotosUseCase:GetRecentPhotosUseCase= mockk()
private val recentPhotosRepository:RemoteRecentPhotosRepository= mockk()
private val mainViewModel by lazy { RecentPhotosViewModel(getRecentPhotosUseCase) }
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
@Before
fun setupBefore(){
startKoin {
androidContext(App.getInstance())
if (BuildConfig.DEBUG) androidLogger(Level.DEBUG)
modules(appModules domainModules dataModules)
}
}
@Test
fun `get recent photo success`(){
val map: MutableMap<String, String> = HashMap()
map["format"] = "json"
map["method"] = "flickr.photos.getRecent1"
map["nojsoncallback"]="1"
map["per_page"]="20"
map["page"]= "1"
val recentPhotoResponse = mockk<RecentPhotos>()
//1- Mock calls
every { runBlocking {recentPhotosRepository.getRecentPhotos(map)} } returns Success(recentPhotoResponse)
mainViewModel.viewState.observeForever { }
runBlocking {mainViewModel.getRecentPhotos(map)}
val getRecentPhotoSuccess= mainViewModel.viewState.value
MatcherAssert.assertThat(
"Received result [$getRecentPhotoSuccess] amp; mocked ${OnSuccess(recentPhotoResponse)} must be matches on each other!",
getRecentPhotoSuccess,
CoreMatchers.`is`(OnSuccess(recentPhotoResponse))
)
}
}
но когда я запускаю тест, он выдает мне эту ошибку:
io.mockk.MockKException: no answer found for: GetRecentPhotosUseCase(#1).invoke({per_page=20, method=flickr.photos.getRecent1, format=json, page=1, nojsoncallback=1}, continuation {})
Комментарии:
1. Поделитесь своим классом GetRecentPhotosUseCase
Ответ №1:
Вам нужно сообщить mockk, каково возвращаемое значение getRecentPhotosUseCase.function(...)
. Вы делаете это следующим образом: every { mock.call(...) } returns Value
. Вы можете либо указать any()
параметры, либо использовать конкретные значения:
every { getRecentPhotosUseCase.function(any(), any(), ...) } returns YourResultValue
// or
every { getRecentPhotosUseCase.function(per_page = 20, ...) } returns YourResultValue
В качестве альтернативы, если вы не хотите издеваться над результатом GetRecentPhotosUseCase
(возможно, потому, что это важно для вашего тестового сценария), вы используете расслабленный макет:
Расслабленный макет — это макет, который возвращает некоторое простое значение для всех функций. Это позволяет пропустить указание поведения для каждого случая, в то же время позволяя ограничивать то, что вам нужно. Для ссылочных типов возвращаются связанные макеты.
val getRecentPhotosUseCase:GetRecentPhotosUseCase= mockk(relaxed = true)
Комментарии:
1. Спасибо, чувак. ваше решение сработало. но я не знаю, почему Assert — это сбой. оба класса onSuccess одинаковы, но @number отличается, и я не понимаю. Я обновил свой вопрос.
2. Добро пожаловать. Но я предлагаю вам отменить обновление, и вы задаете новый вопрос. Потому что, если другие люди читают этот (обновленный) вопрос, этот ответ больше не соответствует вопросу. Вы можете написать комментарий с комментарием к вашему новому вопросу.