https://kotlinlang.org logo
Title
k

Kulwinder Singh

03/10/2020, 1:30 PM
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 ?
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

Cody Engel

03/10/2020, 3:31 PM
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

Kulwinder Singh

03/10/2020, 3:38 PM
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

Cody Engel

03/10/2020, 3:42 PM
Should be something like
verify { myClass.sendMessage(request) }
k

Kulwinder Singh

03/11/2020, 1:56 AM
@Cody Engel again
verify
is saying that instances of RequestBody don't match
c

Cody Engel

03/11/2020, 2:08 AM
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

Kulwinder Singh

03/11/2020, 2:41 AM
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

Cody Engel

03/11/2020, 2:41 AM
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

Kulwinder Singh

03/11/2020, 2:43 AM
i have tried slot actually but got below exception
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
val firstSlot= slot<RequestBody>()
every {	myClass.sendMessage(firstSlot) } answers { something }

it("sendSomeMessage") {
	...
	verify {
		myClass.sendMessage(firstSlot.captured)
	}
}
c

Cody Engel

03/11/2020, 2:48 AM
That’s not the proper usage
Within send message should capture(firstSlot)
Then after the verify could do something like assertThat(firstSlot.captured)
k

Kulwinder Singh

03/11/2020, 2:54 AM
@Cody Engel sorry i have actually used
every {	myClass.sendMessage(capture(firstSlot)) } answers { something }
(its changed while i edited before asking)
c

Cody Engel

03/11/2020, 3:01 AM
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

Kulwinder Singh

03/11/2020, 3:05 AM
@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

Cody Engel

03/11/2020, 1:28 PM
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

Kulwinder Singh

03/11/2020, 1:46 PM
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

Cody Engel

03/11/2020, 4:15 PM
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

Kulwinder Singh

03/12/2020, 5:17 AM
yeah true 👍