Reputation: 431
I'm trying to test my view model with mockK library. but i can not figure it out how to do that. This is my class. I have a use case and a repository:
@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] & mocked ${OnSuccess(recentPhotoResponse)} must be matches on each other!",
getRecentPhotoSuccess,
CoreMatchers.`is`(OnSuccess(recentPhotoResponse))
)
}
}
but when i run the test it gives me this error:
io.mockk.MockKException: no answer found for: GetRecentPhotosUseCase(#1).invoke({per_page=20, method=flickr.photos.getRecent1, format=json, page=1, nojsoncallback=1}, continuation {})
Upvotes: 3
Views: 2538
Reputation: 2690
You need to tell mockk what the return value of getRecentPhotosUseCase.function(...)
is. You do this like: every { mock.call(...) } returns Value
. You can either put any()
for the parameters, or you can use concrete values:
every { getRecentPhotosUseCase.function(any(), any(), ...) } returns YourResultValue
// or
every { getRecentPhotosUseCase.function(per_page = 20, ...) } returns YourResultValue
Alternatively if you do not wanna mock the result of GetRecentPhotosUseCase
(maybe because it's irelevant for your test scenario) you use a relaxed mock:
A relaxed mock is the mock that returns some simple value for all functions. This allows to skip specifying behavior for each case, while still allowing to stub things you need. For reference types, chained mocks are returned.
val getRecentPhotosUseCase:GetRecentPhotosUseCase= mockk(relaxed = true)
Upvotes: 2