【问题标题】:Mocking slf4j with Spock用 Spock 模拟 slf4j
【发布时间】:2015-08-03 00:42:36
【问题描述】:

我有一个用@Slf4j 注释的 Groovy 类,所以它有一个私有的 final 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

【问题讨论】:

标签: groovy mocking slf4j spock


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    这可能会导致测试不那么脆弱。

    【讨论】:

    • 我该怎么做?我尝试使用projects.lidalia.org.uk/slf4j-test,但我的类路径已经包含一个 slf4j 后端,所以我无法更改它(并且不想为我的所有测试更改它)。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2022-06-11
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 2018-08-24
      相关资源
      最近更新 更多