MockK offers a convenient `@MockKExtension.CheckUn...
# testballoon
b
MockK offers a convenient
@MockKExtension.CheckUnnecessaryStub
annotation that can be added to a test class. As far as I can tell, TestBalloon does not expose a class to annotate. Is there some other way to achieve the same effect? https://github.com/mockk/mockk#automatic-unnecessary-stubbing-check
o
Yes, TestBalloon uses plain Kotlin, so something like that might suit your needs:
Copy code
fun TestConfig.withMocking() = aroundEachTest { action ->
    try {
        action()
    } finally {
        checkUnnecessaryStub()
    }
}

val MyMockingTests by testSuite(testConfig = TestConfig.withMocking()) {
    checkUnnecessaryStub()
}
You could look into the other
TestConfig.around...
functions for alternatives. And as always with
TestConfig
, you can apply the configuration via a
testConfig
parameter at any suite level, up to the global
TestSession
. The configuration will then be effective on that level and everywhere below. Does that help?
b
Very elegant! I love the way that you built this out of TestBalloon's existing features. Bravo on your API design. That being said, after further experimentation I decided that
checkUnnecessaryStub()
with no arguments is too fragile when used with concurrent tests: it creates race conditions due to its use of a MockK-internal global registry of mock instances. Same goes for
clearMocks()
when used with no arguments, which otherwise would also have made sense to call here. I want to let TestBalloon parallelize aggressively, so MockK features that use mutable global state are a bad fit. I ultimately ended up creating two convenience functions to manage mock instances. These functions are compatible with TestBalloon, but are in no way specific to TestBalloon.
o
Thanks, great that you're enjoying TestBalloon's composable API design! Of course, global mutable state without proper synchronization is incompatible with parallelization (or even just concurrency). That's why there are compartments (like
TestCompartment.Sequential
) which can safely separate such legacy architectures from test suites using parallelization. But if you can let your mocking library operate in a thread-safe (or rather coroutine-safe) way, why not go the way you have chosen? 👏 NOTE to readers as Slack blocks editing: The second call to
checkUnnecessaryStub()
was a copy-paste error and should be replaced with
test
or
testSuite
calls.
agree 1