lupuuss / Mokkery

The mocking library for Kotlin Multiplatform, easy to use, boilerplate-free and compiler plugin driven.
https://mokkery.dev
Apache License 2.0
161 stars 7 forks source link

Provide callback mechanism when calls are made #34

Open dalewking opened 1 month ago

dalewking commented 1 month ago

I would like to see a global call back mechanism to monitor calls to mocks and possibly even modify the behavior.

One use for this would be for logging. In complex cases where the SUT is interacting with multiple mocks it is helpful to debug to see what parameters were passed to the mock and what the mock is returning via logging.

It would also provide a way to handle my request in #20

As I see it at the minimum such a callback interface could look like:

    interface MockCallback {
        fun called(scope: FunctionScope, result: Result<Any>) : Result<Any>
        suspend fun calledSuspend(scope: FunctionScope, result: Result<Any>) : Result<Any> = called(scope, result)
    }

This lets you:

lupuuss commented 1 month ago

So it's more of an interceptor mechanism.

Technically, implementing the ability to intercept mock calls is not very complicated on its own. However, doing it in the right place can be challenging and requires careful consideration.

The bigger issue is registering that interceptor globally in tests, because there's no single entry point for doing this in Kotlin Multiplatform. In JVM projects, ServiceLoaders are available and sufficient, but for other targets, it's not as straightforward. There are some tricks, like using the EagerInitialization annotation, but it's marked as deprecated. On the other hand, Ktor uses this trick, so maybe it won't be removed without a replacement.

In general, I should be able to implement intercepting on its own, but initial release might not contain global registering.