与Spock嘲笑slf4j

时间:2015-05-21 11:17:50

标签: groovy mocking slf4j spock

我有一个使用@Slf4j注释的Groovy类,因此它获得了一个私有的最终Logger log字段,其用法我想测试。我想继续使用@Slf4j并且不再公开log字段以启用测试。

我正在使用Spock 1.0编写测试,并尝试使用Spock的集成模拟和存根功能来完成此操作。全局存根应该可以帮助我拦截LoggerFactory调用以获取实际的Logger实例,所以我目前的猜测是:

LoggerFactory logFactory = GroovyStub(global: true)
logFactory.getLogger(_) >> Mock(Logger)
// create my @Slf4j-annotated object afterwards

有趣的是,拦截实际上有效,println确认类实际上获得了一个对象Mock for type 'Logger' named 'dummy',但是指示存根返回模拟的第二个语句似乎没有捕获。相反,默认存根行为返回另一个存根,当然不能用于模拟:

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.

我需要更改什么才能让存根LoggerFactory返回模拟Logger

3 个答案:

答案 0 :(得分:2)

您需要使用反射设置私有最终日志字段,如下所述:Unit testing of a class with StaticLoggerBinder

答案 1 :(得分:0)

如果要测试日志输出,为什么不让日志框架完成工作并测试结果(日志文件)?您只需要将日志输出连接到测试运行后访问的文件。

这可能会导致较少的脆弱测试。

答案 2 :(得分:0)

您可以使用slf4j测试后端来声明spf4j-slf4j-test之类的日志记录行为。 Slf4j将在类路径中选择第一个后端实现,这就是为什么需要在项目依赖项中首先列出测试后端依赖项的原因。 (在测试范围内)。