Mocking an iterator is a little bit special since it uses dynamic hasNext() and next() methods. Different approaches can be used to do this but here 2 of them are described.
The first method uses the signature of Mockito's thenReturn(T...) method:
"iterator" should "be mocked thanks to varargs from Mockito's thenReturn method" in { val mockedIterator = Mockito.mock(classOf[Iterator[Int]]) Mockito.when(mockedIterator.hasNext).thenReturn(true, true, false) Mockito.when(mockedIterator.next()).thenReturn(1, 2) var numbers: Seq[Int] = Seq() while (mockedIterator.hasNext) { numbers = numbers :+ mockedIterator.next() println(numbers) } numbers should contain allOf(1, 2) }
But the previous method is only possible when we know the number of values in advance. Another constraint is the ability to define these values by hand. It's easy for 3 possible entries but not so possible for 300. The next method solves this problem:
"iterator" should "be mocked thanks to delegation" in { val inputNumbers = Seq(1, 2, 3, 4) val numbersIterator = inputNumbers.iterator trait WrappedIterator { def getIterator: Iterator[Int] def hasNext: Boolean def next: Int } val wrappedIterator = Mockito.mock(classOf[WrappedIterator]) Mockito.when(wrappedIterator.getIterator).thenReturn(numbersIterator) // Note that the ue of thenReturn(...) won't work because it will always return the 1st // state of the iterator Mockito.when(wrappedIterator.hasNext).thenAnswer((invocation: InvocationOnMock) => { numbersIterator.hasNext }) Mockito.when(wrappedIterator.next).thenAnswer((invocation: InvocationOnMock) => numbersIterator.next()) var numbers: Seq[Int] = Seq() while (wrappedIterator.hasNext) { numbers = numbers :+ wrappedIterator.next } numbers should contain allOf(1, 2, 3, 4) }