I just added a dependency which pulled in slf4j an...
# mockk
I just added a dependency which pulled in slf4j and slf4j-android into my kotlin android project. It looks like JvmMockKGateway.Companion logs from its init {} block, and if slf4j is present, it uses slf4j. And with the slf4j-android binding present, slf4j will call into android.util.Log, which will raise an assertion error if it’s called from a unit test, when unmocked, resulting in an exception, resulting in a NoClassDefFoundError for JvmMockKGateway.
assuming you're in an Android unit test, I don't see why this would result in NoClassDefFoundError - it should be running with a stub Android API
(which still throws, but can be silence with
android { testOptions { unitTests.isReturnDefaultValues = true } }
So, I’ve been trying to avoid turning on isReturnDefaultValues, because their own documentation warns you away from it
@ephemient but as you point out, the android api throws. Which unfortunately, it throws from JvmMockKGateway.Companion’s init { } block
which means that the class encounters an exception during initialization, which in turn results in a NoClassDefFoundException.
I’m not sure if this amounts to a bug in mockk --- if it is, I’m happy to go report it!
(that it logs from there, I mean)
Apologies for the delayed response.
I wouldn't consider it mockk bug - seems like anything that logs would have problems in this setup.
yeah. but what I mean is, it seems unsafe for mockk to be logging from its class initializer (isn’t it?)
given that some log implementations will throw exceptions
which the normal way to get around is to mock them.
at least, unsafe for it to be logging via slf4j.
at the very least it seems like it should have a try/except around the log statement and/or a logging fallback mode
because there’s no way for people to using mockk to work around it, since by the time it makes it to the caller it’s a NoClassDefFoundException
I don't agree - loggers should generally not throw. if an exception is recoverable it should be handled inside the logger and if it is not recoverable then the application should not continue
ideally you either configure slf4j not to use -android in your unit test, or configure the unit test to allow the android logger to work
I agree that they shouldn’t
but android’s does!
when run in a test environment, which is specifically when mockk is used.
and unfortunately, it’s an external dependency that brings in -android
so we have no control over it
any dependency that brings in a specific slf4j binding is broken :(
100% agree
and we’ve reported it to them too
but can’t always rely on external vendors being well-behaved 😕
I may report it as an issue anyway if only to have the discussion (unless you think it’s a bad idea)
because it feels like, yes, this is a misbehaving dependency, but the failure mode that results seems far more catastrophic than it has to be
IMO it isn't a configuration that MockK should be expected to handle, and you should still have other workarounds
using https://github.com/ljacomet/logging-capabilities to force it to a different slf4j binding, for example
Ahhh --- thanks for pointing me in that direction!
hadn’t started digging into ways to override the slf4j binding yet
which I definitely should have done before coming here 😐
thanks again. I’ll check it and similar tools out.
and sorry for the noise!