How to test through io.mockk a method that was called several times with different parameters?
Asked Answered
D

2

10

PS: Code will be in Koltin

For example, I have my service class that does something and injects some other service.

class MyService(
   private val someOtherService: OtherService
) {
   fun doSomething() {
       someOtherService.someMethod("foo")
       someOtherService.someMethod("bar")
       someOtherService.someMethod("baz")
   }
}

Here is my test to my MyService class which mocks OtherService:

internal class MyServiceTest {
    @MockkBean(relaxed = true)
    private lateinit var someOtherService: OtherService

    @Test
    fun `my test description`() {
        every { someOtherService.someMethod(any()) } just Runs

        verify(exactly = 1) {
            someOtherService.someMethod(
                    match {
                        it shouldBe "bar"
                        true
                    }
            )
        }
    }

As a result, "bar" parameter will be expected but will be "foo" parameter instead and the test will fail.

Reason: someOtherService.someMethod("foo") will have called before someOtherService.someMethod("bar").

However, I want to verify that every method called exactly once. How I can do that?

Diphosgene answered 14/10, 2019 at 10:21 Comment(0)
T
17

You could just:

verifySequence {
  someOtherService.someMethod("foo")
  someOtherService.someMethod("bar")
  someOtherService.someMethod("baz")
}

It verifies that only the specified sequence of calls were executed for mentioned mocks.

Mockk verification-order

If not, you could capture the parameter using a list and verify the values later.

Mockk capturing

Taxpayer answered 14/10, 2019 at 10:51 Comment(1)
Can the OP verify that this is an acceptable answer? Thanks.Hawserlaid
D
6

Service method to test

someMethod(str: String) : String

When you need to verify multiple calls to the same method with different parameters

 val stringSlots = mutableListOf<String>()
 every { someService.someMethod(capture(stringSlots)) } answers { "string" }

Verification

stringSlots.size shouldBe <Number of calls expected>

val firstSlot = stringSlots[0]
val secondSlot = stringSlots[1]
val thirdSlot = stringSlots[1]
// Do any verifications after 

firstSlot shouldBe "foo"
secondSlot shouldBe "bar"
...
Dill answered 16/1 at 0:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.