MocKMP

Compile-time mocks and fakes for Kotlin Multiplatform tests — generated by a KSP processor, not by reflection.

MocKMP turns a plain interface or abstract class into a mock or a fake for your tests. You ask for what a test needs with an annotation — @Mock, @Fake, @UsesMocks, @UsesFakes — and a KSP processor generates the implementation, ready to inject.

MyTest.kt
class MyTest : TestsWithMocks() {
    override fun setUpMocks() = mocker.injectMocks(this)

    @Mock lateinit var view: View
    @Fake lateinit var model: Model

    val controller by withMocks { Controller(view = view, firstModel = model) }

    @Test fun controllerTest() {
        every { view.render(isAny()) } returns true
        controller.start()
        verify { view.render(model) }
    }
}

No reflection, no dynamic proxies, no "relaxed" mode papering over a call nobody mocked. An interface, a generated implementation, and a compiler that rejects a mock or a fake for a type that can’t be one.

Why MocKMP

Compile-time, not reflection. A KSP processor generates a real class implementing the interface or abstract class you asked to mock or fake, so it behaves identically on every target — including the ones with no runtime reflection at all, like iOS, JS and Wasm.

Mocking and faking answer different questions. A mock’s behaviour is defined per test, and every call on it can be verified; a fake’s data is inert and zero-valued, and nothing about it is checked. Reach for a fake when a collaborator only needs to exist, and a mock when the test needs to configure or verify it.

Nothing is generated until you ask for it. @UsesMocks / @UsesFakes — or a @Mock / @Fake property — requests exactly the types a given test needs, so an interface used across a large codebase doesn’t grow generated code everywhere it’s declared, only where it’s actually mocked or faked.

Injection kills the constructor boilerplate. Annotate properties @Mock or @Fake and call mocker.injectMocks(this); inherited properties are injected too, so a shared base test class works exactly as if its mocks had been declared locally.

The TestsWithMocks helper collapses the ceremony further. Inherit it and get a Mocker, an automatic reset before every test, withMocks property delegates rebuilt fresh each time, and every / everySuspending / verify / verifyWithSuspend callable without the mocker. prefix.

Constraints read the same in a definition and in a verification. isAny, isEqual, isNotNull, isInstanceOf, and any custom constraint you write with isValid, work identically whether they appear inside every or inside verify — one matcher vocabulary, not two.

Multiplatform, with no platform-specific surprises. mockmp-runtime targets every platform MocKMP supports and behaves the same on each of them.

How to read this documentation

  • Getting started gets a first mock and a first fake working in a few minutes.

  • The Core section explains setup, mocking, faking, injection and the test helper from the ground up.

  • The Migration section helps you move from a previous major version.