for MockK, i'm getting `MockKException: no answer ...
# mockk
k
for MockK, i'm getting
MockKException: no answer found for: MyClass(#1).sendMessage(okhttp3.RequestBody$2@4ed4bd33)
, actually RequestBody's properties are same just instance is different. that's why it did not matches parameters but if i add
any()
instead of requestbody it works. is there anything else i can use instead of
any()
here ?
Copy code
every {	myClass.sendMessage(MockRequest.createTestBody(value="text")) } answers { something }

....

class SomeObject(myClass:MyClass){
	fun doSomething(text: String): Flowable<Result<Boolean>> {
        val request = MockRequest.createTestBody(text)
		myClass.sendMessage(request)
	}
}
....
i have checked documentation of mockk but didn't found anything, that's why asked here:
c
Honestly I tend to defer to using
any
and if it's important to verify the contents I'll use a
verify
call on the mock to verify that the correct value was being passed (assuming that's important for the test).
k
i was also thinking this, can you please let me know how can i verify in my above code ?
@Cody Engel i want to verify that value text is passed in function
c
Should be something like
verify { myClass.sendMessage(request) }
k
@Cody Engel again
verify
is saying that instances of RequestBody don't match
c
If they don’t match then they don’t match. What is the test testing? Do you need to validate the entire request body is the same or do you just need to know certain values are the same?
k
actually i only need to know if values in RequestBody are same? @Cody Engel
in my above example i know values are same but instance is not matching
c
You can use a slot and then do a specific assertion on the captured value.
They are functionally the same as argument captors from Mockito
k
i have tried slot actually but got below exception
Copy code
lateinit property captured has not been initialized
kotlin.UninitializedPropertyAccessException: lateinit property captured has not been initialized
	at io.mockk.CapturingSlot.getCaptured(API.kt:2529)
@Cody Engel i have tried like this
Copy code
val firstSlot= slot<RequestBody>()
every {	myClass.sendMessage(firstSlot) } answers { something }

it("sendSomeMessage") {
	...
	verify {
		myClass.sendMessage(firstSlot.captured)
	}
}
c
That’s not the proper usage
Within send message should capture(firstSlot)
Then after the verify could do something like assertThat(firstSlot.captured)
k
@Cody Engel sorry i have actually used
every {	myClass.sendMessage(capture(firstSlot)) } answers { something }
(its changed while i edited before asking)
c
I’ve normally done the capture within the verify instead of the every block. You can do it within the every but most examples show that being used when you want the captured value to be returned by the answers block
k
@Cody Engel you are right, actually in my code there was second
every
block which was similar to first but that was not using
capture
. so i commented that and now i works.
@Cody Engel thanks a lot for your help. your method really helped me 👍
@Cody Engel do you know how we can read content inside RequestBody ?
c
Yeah you're welcome, and I don't write tests around OkHttp too often, I know on the occasions I have had to it was quite gnarly though. Unfortunately I don't have any advice for reading content within the RequestBody though.
Unrelated, but kind of related. If you are able to, switching to Retrofit with converters can be incredibly useful as it generates that code for you so it can be assumed it's been tested and works correctly. Because of that, I rarely write unit tests that are interacting with OkHttp at any level.
k
actually due to client’s requirements i have to write tests :)
i have used this to read RequestBody https://github.com/square/okhttp/issues/1891
c
Writing tests is good, but being able to minimize the number of tests is also good. Retrofit can be a good option to reduce what tests you have to write, similar to Kotlin, you don't write tests to verify
null
states if the type isn't nullable.
k
yeah true 👍