I have a Groovy class annotated with @Slf4j
, so it gets a private final Logger log
field, whose usage I'd like to test. I want to continue using @Slf4j
and not expose the log
field any further just to enable testing.
I'm writing my tests using Spock 1.0 and tried to accomplish this using Spock's integration mocking and stubbing functionality. Global stubbing should help me intercept the LoggerFactory
invocation to get the actual Logger
instance, so my current guess is this:
LoggerFactory logFactory = GroovyStub(global: true)
logFactory.getLogger(_) >> Mock(Logger)
// create my @Slf4j-annotated object afterwards
Interestingly, the interception actually works, println
confirms that the class actually gets an object Mock for type 'Logger' named 'dummy'
, but the second statement that instructs the stub to return a mock does not seem to catch. Instead the default stub behaviour returns yet another stub, that cannot be used for mocking of course:
org.spockframework.runtime.InvalidSpecException: Stub 'dummy' matches the following required interaction:
1 * plugin.log.warn(_) (0 invocations)
Remove the cardinality (e.g. '1 *'), or turn the stub into a mock.
What do I need to change to let the stubbed LoggerFactory
return a mock Logger
?
You need to set the private final log-field with reflection, as explained here: Unit testing of a class with StaticLoggerBinder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With