Проверка Mockk глубоких заглушек не удалась

#kotlin #mocking #mockk

Вопрос:

Версия Kotlin: 1.5 — версия Mockk 1.12.0

Я знаю, что каждый раз, когда мок возвращает мок, мы каким-то образом нарушаем Закон Деметры. В моем приложении я использую RedisTemplate, который для каждой операции делегируется другому объекту, например

 redisTemplate.opsForSet().members()
 

или

 redisTemplate.opsForSet().remove()
 

В этих случаях мне приходится издеваться над издевкой. Короче говоря, я попытался упростить ситуацию на примере, как показано ниже:

 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()
      }
    }
  }
}
 

Мой тестовый класс выглядит следующим образом:

 @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?