Skip to content

Mocking and verifying

Iman Irandoost edited this page Mar 18, 2022 · 25 revisions

This page provides some examples on how to mock classes and verify them with Mockito-Kotlin.
To find more information on how Mockito works, see the official Mockito website.

Mockito-Kotlin provides a set of top-level functions that you can use instead of Mockito's static methods, such as mock(), any() and eq(). When importing these functions, be careful to import them from the org.mockito.kotlin package.

Creating mocks

When calling mock(), you don't have to pass in the class instance anymore. If the type can be inferred, you can just write:

val mock : MyClass = mock()

If the type cannot be inferred directly, use:

val mock = mock<MyClass>()

Passing a new mock as a parameter becomes:

myClass.test(mock())

Stubbing

Mockito-Kotlin provides whenever in favor of when. Basic usage stays the same:

whenever(mock.stringValue()).thenReturn("test")

Alternatively, you can pass a lambda expression to mock(). The lambda expression is of type KStubbing<T>.() -> Unit, where T is the type of the mocked class. KStubbing<T> provides a method on which takes a function T.() -> R, so you can directly call the method to mock:

val mock = mock<MyClass> {
    on { stringValue() }.doReturn("test")
}

doReturn is marked as an infix function, so you can use:

val mock = mock<MyClass> {
    on { stringValue() } doReturn "test"
}

If you want to use KStubbing<T> on a mocked object, use the stub extension function:

mock.stub {
    on { stringValue() } doReturn "test"
}

If you want to stub a suspend function, use the onBlocking method:

mock.stub {
    onBlocking { stringValue() } doReturn "test"
}

Verifying

Verifying behavior looks a lot like the original version:

verify(myClass).doSomething("test")

Just as with mock(), you don't have to specify the type of any when you pass it as a parameter:

verify(myClass).doSomething(any())

However, If you want to restrict any to a certain subclass, use:

verify(myClass).doSomething(any<MySubClass>())

For generic arrays, use anyArray().

Properties

You can also verify the setting of properties. For example:

interface Foo {
  var bar : String
}

@Test
fun test() {
  val foo = mock<Foo>()
  foo.bar = "test"
  verify(foo).bar = "test"
  // or you can use a setter argument
  doAnswer { it.getArgument(0) }.`when`(foo).bar = any()
}

Argument Matchers

Using higher-order functions, you can write very clear expectations about expected values. For example:

verify(myClass).setItems(argThat { size == 2 } )

If you prefer a more natural read, you can use:

verify(myClass).setItems(argForWhich { size == 2 } )

Both argThat and argForWhich take in a function T.() -> Boolean, where T is the type of the parameter.

If you want to do more assertions on the received argument, you can use check:

verify(myClass).setItems(check { 
  assertThat(it.size, is(2))
  assertThat(it[0], is("test"))
})

check accepts a function (T) -> Unit, and thus does not report anything back to Mockito. If you want your test to fail inside a check invocation, you should make sure the body throws an error (like assertThat or assertEquals would do).

Argument Captors

Argument Captors can be used to capture argument values for further assertions, just like in Mockito. For example:

argumentCaptor<String>().apply {
  verify(myClass, times(2)).setItems(capture())

  assertEquals(2, allValues.size)
  assertEquals("test", firstValue)
}

InOrder

In Mockito-Kotlin, inOrder can take in a lambda for easy verification:

val a = ...
val b = ...

inOrder(a,b) {
  verify(a).doSomething()
  verify(b).doSomething()
}