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:
…will generate the |