The test class helper

MocKMP provides the TestsWithMocks helper class that your test classes can inherit from. It provides the following benefits:

  • Provides a Mocker.

  • Resets the Mocker before each tests.

  • Provides withMocks property delegates to initialize objects with mocks.

  • Allows to call every, everySuspending, verify, and verifyWithSuspend without mocker..

It does not come with the standard runtime (as it forces the dependency to JUnit on the JVM), so to use it you need to either:

  • define usesHelper = true in the MocKMP Gradle plulgin configuration block,

  • or add the mockmp-test-helper implementation dependency.

Here’s a test class example with TestsWithMocks:

@UsesFakes(User::class)
class MyTests : TestsWithMocks() { (1)
    override fun setUpMocks() = injectMocks(mocker) (2)

    @Mock lateinit var db: Database
    @Mock lateinit var api: API

    @Fake lateinit var user: User

    val controller by withMocks { ControllerImpl(db, api) } (3)

    @Test fun controllerTest() {
        every { view.render(isAny()) } returns true (4)
        controller.start()
        verify { view.render(model) } (4)
    }
}
1 The class inherits TestsWithMocks, which provides helpers.
2 setUpMocks must be overriden, and can generally be just a delegation to the injectMocks generated function.
3 Controller will be (re)created before each tests with the new mock dependencies.
4 Note the absence of mocker. as you can use every and verify directly.
Properties delegated to withMocks will be (re)initialized before each tests, after the mocks have been (re)injected.

Because of this issue, you cannot consider that the mocks have been initialized in yout @BeforeTest methods. You can override initMocksBeforeTest if you need to initialize your mocks before each test:

class MyTests : TestsWithMocks() {
    override fun initMocksBeforeTest() {
        // Access all injected values:
        // mocks, fakes & withMocks properties
    }
}

In case your test class already extends another class, you can use the ITestsWithMocks interface instead:

@UsesFakes(User::class)
class MyTests : MySuperAbstractTests(), ITestsWithMocks { (1)

    override val mocksState = ITestsWithMocks.State() (2)

    override fun setUpMocks() = injectMocks(mocker)

    // ...your tests...
}
1 The class implements the ITestsWithMocks interface, which provides all helper methods.
2 The class needs to provide an ITestsWithMocks.State (since the interface cannot provide one).