Injecting your test classes

Instead of manually creating your own mocks & fakes, it can be useful to inject them in your test classes, especially if you have multiple tests using them.

class MyTests {
    @Mock lateinit var db: Database
    @Mock lateinit var api: API

    @Fake lateinit var user: User

    lateinit var controller: Controller

    val mocker = Mocker()

    @BeforeTest fun setUp() {
        mocker.reset() (1)
        mocker.injectMocks(this) (2)
        controller = ControllerImpl(db, api) (3)
    }

    @Test fun controllerTest() {
        mocker.every { api.getCurrentUser() } returns user
        mocker.every { db.saveUser(isAny()) } returns Unit
        controller.start()
        mocker.verify {
            api.getCurrentUser()
            db.saveUser(user)
        }
    }
}
1 Resets the mocker before any test (which removes all mocked behaviour & logged calls), so that each test gets a "clean" mocker.
2 Injects mocks and fakes.
3 Create classes to be tested with injected mocks & fakes.

As soon as a class T contains a @Mock or @Fake annotated property, a Mocker.injectMocks(receiver: T) function will be created by the processor.

Don’t forget to reset the Mocker in a @BeforeTest method!

Inherited properties are injected as well, so you can put the mocks & fakes that all your tests need in a shared base class:

abstract class BaseTests {
    @Mock lateinit var db: Database (1)

    val mocker = Mocker()

    @BeforeTest fun setUp() {
        mocker.reset()
        mocker.injectMocks(this) (2)
    }
}

class MyTests : BaseTests() {
    @Mock lateinit var api: API
}
1 Declared in the base class, but injected into every subclass.
2 Resolves to injectMocks(receiver: MyTests), which sets both db and api.
The base class must be in the same module as its subclasses: the processor only sees the annotations of the module it is running on.

You can inject other classes than test classes:

class MyMocks {
    @Mock lateinit var db: Database
    @Mock lateinit var api: API
}

…​will generate the Mocker.injectMocks(receiver: MyMocks) function.