-
Notifications
You must be signed in to change notification settings - Fork 202
Mocking and verifying
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.
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())
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 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()
.
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()
}
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 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)
}
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()
}