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?