How to enable STRICT_STUBS while using Mockito.mock()

Viewed 1612

I've found only three ways how to enable STRICT_STUBS in Mockito (See documemantation)

  1. MockitoJunitRunner

  2. MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS)

  3. Mockito.mockitoSession() .initMocks(this) .strictness(Strictness.STRICT_STUBS) .startMocking()

All of them require to declare stubs via annotations (@Mock lateinit var api: MyApi ). But I'm using mockito-kotlin and declare stubs like that:

val api: MyApi = mock()

or like that:

val api:MyApi = mock{
  on { call("expected-param") } doReturn something
}

Under the hood it uses Mockit.mock method.

Question 1: how can I enable STRICT_STUBS when I use Mockit.mock ?

Question 2: Perhaps it's possible to enable STRICT_STUBS for everything regardless how mock is defined?

Update 1. Test example

interface Foo {
    fun doFoo(value: String): String
}

class Boo(private val foo: Foo) {
    fun doBoo(value: String): String {
        return foo.doFoo("$value with Boo")
    }
}

class ExampleTest {
    @get:Rule val rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS)
    // doesn't work when replaced with var mockedFoo: Foo = Mockito.mock(Foo::class.java)
    @Mock lateinit var mockedFoo: Foo
    lateinit var booUnderTest: Boo

    @Before fun setUp() {
        booUnderTest = Boo(mockedFoo)
    }

    @Test fun withEmptyString() {
        `when`(mockedFoo.doFoo(" with Boo")).thenReturn("empty boo")
        // should fail, because this interaction is not used
        `when`(mockedFoo.doFoo("Foo with Boo")).thenReturn("complete")
        booUnderTest.doBoo("")
        verifyNoMoreInteractions(mockedFoo)
    }

    @Test fun withRealString() {
        `when`(mockedFoo.doFoo("Foo with Boo")).thenReturn("complete")
        booUnderTest.doBoo("Foo")
        // this test should pass because with STRICT stubbing no need to call verify
        verifyNoMoreInteractions(mockedFoo)
    }
}

Strict stubbing works, when stub is defined as @Mock lateinit var mockedFoo: Foo. When I replace it with var mockedFoo: Foo = Mockito.mock(Foo::class.java) strict stubbing is not working anymore.

Update 2. Answer.. Mockito.mock works, if called after enabling strict mode.

class ExampleTest {
    @get:Rule val rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS)
    lateinit var mockedFoo: Foo
    lateinit var booUnderTest: Boo
    @Before fun setUp() {
        mockedFoo = Mockito.mock(Foo::class.java)
        booUnderTest = Boo(mockedFoo)
    }

    @Test fun withEmptyString() {
        `when`(mockedFoo.doFoo(" with Boo")).thenReturn("empty boo")
        // should fail, because this interaction is not used
        `when`(mockedFoo.doFoo("Foo with Boo")).thenReturn("complete")
        booUnderTest.doBoo("")
        verifyNoMoreInteractions(mockedFoo)
    }

    @Test fun withRealString() {
        `when`(mockedFoo.doFoo("Foo with Boo")).thenReturn("complete")
        booUnderTest.doBoo("Foo")
        // this test should pass because with STRICT stubbing no need to call verify
        verifyNoMoreInteractions(mockedFoo)
    }
}
1 Answers

STRICT_STUBS need additional logic to verify what has and what hasn't been invoked after test, that is why it's rather configured on whole test level. That being said, any of the three ways should work with plain Mockito.mock method (and with given example provided it uses Mockito.mock under the hood).

Related