我可以使用Akka的测试事件监听器而不会将我的测试输出污染到STDOUT吗?

时间:2013-11-10 09:27:05

标签: scala akka

作为测试的一部分,我使用EventFilter和TestEventListener来监听日志消息。但是,这样做会导致我的命令提示中出现大量洪水......这使我很难看到我的测试发生。

示例代码:

it("should send a welcome message to the user", SystemFortressTest) {
  val stub = new SubFortressBuildingPermitRefTraitImplStub
  EventFilter.debug(message = "SystemFortressExchange: Received Message: SystemOutput(List(JITMP Booted))", occurrences = 1) intercept {
      stub.buildASubFortress(SystemFortressBlueprintRef)
  }
}

这段代码有效,但它充斥着调试级数据,因为默认情况下TestEventListener打印到STDOUT(因为它是默认记录器的子类,只是直接STDOUT记录)

我可以滚动自己的日志抽象,它位于Akka的顶部,并在它碰到Akka的东西之前从那里过滤消息......所以它不会污染我的命令提示符。 ..但是,如果已经有类似的解决方案,那就太麻烦了。

问题是,如果我使用SL4J Logger,它就无法使用EventFilter。

3 个答案:

答案 0 :(得分:4)

我的工作是:

akka.loglevel = DEBUG
akka.loggers = ["akka.event.slf4j.Slf4jLogger", "akka.testkit.TestEventListener"]

..然后在我的测试中:

system.eventStream.publish(Mute(EventFilter.info()))
system.eventStream.publish(Mute(EventFilter.debug()))

这样:

  • 错误和警告被报告两次(但无论如何都应该修复:))
  • 调试和信息消息仅通过slf4j
  • 报告
  • 您仍然可以使用eventfilters检查特定消息(可能在首先取消静音之后)

请注意,我通常会考虑测试代码味道的日志消息 - 通常更好地检查更多'可观察'的行为。也许将事件发布到事件流。

答案 1 :(得分:0)

您可以使用其他记录器配置日志级别或完全关闭记录器因此,在配置TestEventListener时,您可以指定日志记录,如下所示。

akka.loggers=["akka.testkit.TestEventListener"]
akka.loglevel = OFF

希望这有帮助

答案 2 :(得分:0)

解决方案是创建一个新的侦听器类,它扩展TestEventListener并覆盖print方法,或者不执行任何操作,或者登录首选的日志记录解决方案,而不是直接打印到stdout。然后,您可以在application.conf选项下的akka.loggers中将自定义事件监听器指定为记录器。 (详见https://doc.akka.io/docs/akka/2.5/scala/testing.html

所以你的事件监听器将是:

package mypackage
import akka.testkit.TestEventListener

class SilentTestEventListener extends TestEventListener {
  override def print(event: Any): Unit = ()
}

您可以将以下内容添加到application.conf

akka {
  loggers = [mypackage.SilentTestEventListener]
}

如果您通过更改日志级别来转换日志记录,或使用事件过滤器过滤噪声日志,那么您也无法在测试中监听这些日志,因为这也是通过事件过滤器完成的:记录器只执行日志上的过滤器,直到找到第一个过滤掉日志消息的过滤器。如果它在测试中使用的过滤器之前找到另一个这样的过滤器,那么您的测试将永远不会收到有关日志条目的通知。

另一个更好的解决方案是实现一个事件监听器,它定义自己处理日志的方式,而不是继承和修改StdOutLogger的行为(因为你会期望StdOutLogger的子类登录到stdout ...),但这需要比上面的hacky解决方案更多的努力,因为你必须复制TestEventListener的功能。