Debugging
Mokkery provides tools to simplify debugging in your tests.
Mock state
You can print the state of a mock using printMokkeryDebug:
val mock = mock<Foo>()
// ...
printMokkeryDebug(mock)
This produces a JSON-like structure printed with println:
mock {
id = your.package.Foo(1)
mode = strict
answers {
getAt(index = any()) returns -1
getAt(index = 1) returns 2
getAt(index = 2) returns 4
getAt(index = 3) returns 6
}
calls {
getAt(index = 0)
getAt(index = 1)
getAt(index = 2)
}
}
You can also create this debug string manually using mokkeryDebugString and process it as needed.
Logging calls
To log each call to a mock, register MokkeryCallLogger in call hooks.
Globally
For quick debugging, you can simply use:
MokkeryScope.global.callHooks.beforeAnswering.register(MokkeryCallLogger())
Specific mock
It's possible to register the logger just for a specific mock:
MokkeryScope.from(mock).callHooks.beforeAnswering.register(MokkeryCallLogger())
// or on init
mock<Foo> {
callHooks.beforeAnswering.register(MokkeryCallLogger())
}
Factory
It is possible to register the logger for mock and spy factories. The logger is then applied to every instance created by a given factory:
val factory = mockFactoryOf(Foo::class, Bar::class) {
callHooks.beforeAnswering.register(MokkeryCallLogger())
}
Test class
To log calls only for the duration of a single test class, register the logger before each test and unregister it after:
private val logger = MokkeryCallLogger()
@BeforeTest
fun before() {
MokkeryScope.global.callHooks.beforeAnswering.register(logger)
}
@AfterTest
fun after() {
MokkeryScope.global.callHooks.beforeAnswering.unregister(logger)
}
Module
To register the logger once for a whole module, use a top-level function annotated with @MokkeryModuleInit.
Mokkery calls it once, when Mokkery is first used in the module (e.g. a mock is created):
@MokkeryModuleInit
fun init(scope: MokkeryScope) {
scope.callHooks.beforeAnswering.register(MokkeryCallLogger())
}
The logger registered on scope applies only to mocks created in this module, so mocks created in other modules
(e.g. shared test utilities) are not affected. It's also possible to register the logger in MokkeryScope.global
from an initializer, so it applies to mocks from all modules:
@MokkeryModuleInit
fun init() {
MokkeryScope.global.callHooks.beforeAnswering.register(MokkeryCallLogger())
}
However, the logger is registered only when the initializer runs. For this to work correctly, the first Mokkery call in your tests must come from the module that declares the initializer. Otherwise, calls made before that, e.g. on mocks created by shared test utilities, are not logged.