mockito / mockito-kotlin

Using Mockito with Kotlin
MIT License
3.09k stars 198 forks source link

mock.inOrder {} poor design prevent it to work #472

Open mitasov-ra opened 1 year ago

mitasov-ra commented 1 year ago

Verification.kt contains function:

/**
 * Allows [InOrder] verification for a single mocked instance:
 *
 * mock.inOrder {
 *    verify().foo()
 * }
 *
 */
inline fun <T> T.inOrder(block: InOrderOnType<T>.() -> Any) {
    block.invoke(InOrderOnType(this))
}

Which looks really handy but doesn't work if mock is created with default mock behaviour (all methods return null).

That's because of block: InOrderOnType<T>.() -> Any part, which says that block must return something non-null. Kotlin always adds runtime null-checks at call sites, hence the example code

mock.inOrder {
   verify().foo()
}

will always fail with NPE unless mock is configured with when to return something non-null when .foo() is called.

To fix this, the signature of inOrder should be either

inline fun <T> T.inOrder(block: InOrderOnType<T>.() -> Any?)

or

inline fun <T> T.inOrder(block: InOrderOnType<T>.() -> Unit)

Until then the only way of using it is:

mock.inOrder {
   verify().foo()
   "hey, inOrder creator messed up, so this line is required to make it work"
}