2

Kotlin version: 1.5 - Mockk version 1.12.0

I know that every time a mock returns a mock we are somehow violating the Law of Demeter. In my app I'm using RedisTemplate which for every operation its delegating to another object like

redisTemplate.opsForSet().members()

or

redisTemplate.opsForSet().remove()

In these cases I have to mock a mock. Long story short I tried to simplify by an example as below:

interface Action {
  fun send(): Int
  fun getSteps(): List<Int>
}

class Notifier(val action: Action) {}

class Rabbit {
  fun jump(steps: Int): Boolean {
    return if (steps % 2 == 0) {
      println("Jumping $steps steps .... ")
      true
    } else {
      println("Dont want to jump!")
      false
    }
  }
}

class Service(
    private val rabbit: Rabbit,
    private val notifier: Notifier,
) {

  fun play() {
    for (steps in notifier.action.getSteps()) {
      val jumped = rabbit.jump(steps)
      if (jumped) {
        notifier.action.send()
      }
    }
  }
}

My test class is as below:

@ExtendWith(MockKExtension::class)
class ServiceTest {
  @MockK private lateinit var rabbit: Rabbit
  @MockK private lateinit var notifier: Notifier

  @InjectMockKs private lateinit var service: Service

  @Test
  fun `One notification should be sent`() {
    every { notifier.action.getSteps() } returns listOf(1, 2, 3)
    every { rabbit.jump(1) } returns false
    every { rabbit.jump(2) } returns false
    every { rabbit.jump(3) } returns true
    every { notifier.action.send() } returns 1

    service.play()

    verify(exactly = 3) { rabbit.jump(any()) }
    verify(exactly = 1) { notifier.action.send() }
  }

The problem is every time I run this test it fails with the following error

java.lang.AssertionError: Verification failed: call 1 of 2: Notifier(notifier#1).getAction()). 2 matching calls found, but needs at least 1 and at most 1 calls
Calls:
1) Notifier(notifier#1).getAction()
2) Notifier(notifier#1).getAction()

I know that Mockk is able to handle chain calls but I cannot understand what is the issue. Any thoughts?

Vahid
  • 1,625
  • 1
  • 18
  • 33

0 Answers0