mocking only one call at a time with mockk

Viewed 21182

I know that in order to mock how a method responds, you have to use

every { instanceX.methodB() } returns "42"

I'm trying to mock an iterator, for which you have to mock 2 methods hasNext() and next(), if hasNext() returns true always there will be an infinite loop, if it returns false from the beginning, next() will not return anything.

My question is: is there a way to mock individual calls one by one with mockk, as you can do in mockito ? I couldn't find anything in the docs.

3 Answers

At the excellent post Mocking is not rocket science are documented two alternatives:

returnsMany specify a number of values that are used one by one i.e. first matched call returns first element, second returns second element:

    every { mock1.call(5) } returnsMany listOf(1, 2, 3)

You can achieve the same using andThen construct:

    every { mock1.call(5) } returns 1 andThen 2 andThen 3

Use returnsMany or andThen construct with/instead of return.

Now I have a similar use-case, but for me answers is the appropriate solution as I already have an Iterator in place (and the returned iterator is actually a custom extension of Iterator):

every { mock.bogusIterator() /* : CustomIterator */ } answers { 
  val testIterator = testList.iterator() // just an Iterator
  every { hasNext() } answers { testIterator.hasNext() }
  every { next() } answers { testIterator.next() }
}

where testList contains some predefined values for the test.

returns always returns the value that is given to the function at that time. So using every { hasNext() } returns whatever will always return the value of whatever at that mock declaration time, regardless of whether whatever is mutable or not. On the other hand, with answer you always get the current value of what you return at the time of calling the function. In case someone gets confused by it ;-) Maybe also my further explanation confuses a bit :-)

Related