【问题标题】:Unit testing ConsoleAppender log4j单元测试 ConsoleAppender log4j
【发布时间】:2013-05-28 23:18:45
【问题描述】:

我正在尝试在内部更改自定义异常的布局。为了对此进行单元测试,我希望捕获控制台输出。我之前已经捕获了控制台输出,但我之前使用的方法似乎没有使用 log4j 获得预期的结果。

如果我想捕获控制台输出,我会使用:

    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final PrintStream printStream = new PrintStream(baos);
    System.setOut(printStream);
    System.out.println("Hello world!");
    final String consoleOutput = baos.toString();

consoleOutput 的值将是“Hello World!”。

如果我将其应用于 log4j 使用:

    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final PrintStream printStream = new PrintStream(baos);
    System.setOut(printStream);
    LOGGER.debug("Simple message");
    final String consoleOutput = baos.toString();

控制台输出为空。查看 ConsoleAppender 的 javadoc 我看到了:

默认目标是 System.out。

如果我将代码更改为仅包含以下行:

   LOGGER.debug("Simple message");

我在控制台中看到了预期的结果:

2013-06-02 19:49:46,818 调试 [com.parlance.LoggingTest] - 简单 留言

所以我假设这会起作用,但显然错过了一些东西并且一直在摸不着头脑!

更新

我刚刚尝试了一些东西,如果我将记录器类的创建更改为在我调用 System.setOut 之后,它似乎可以工作:

  final ByteArrayOutputStream baos = new ByteArrayOutputStream();
  final PrintStream printStream = new PrintStream(baos);
  System.setOut(printStream);
  final Logger logger = Logger.getLogger(LoggingTest.class);
  logger.debug("Simple message");
  final String consoleOutput = baos.toString();

这有预期的效果,但如果我想让 Logger 是静态的,那就不是很好了。任何想法为什么会发生这种情况以及如何在不以这种方式声明记录器的情况下解决原始问题?

【问题讨论】:

    标签: java junit log4j


    【解决方案1】:

    似乎System.setOut 在 log4j 初始化后被调用。 log4j 使用System.out 的值进行初始化(它将保留对它的引用)。如您所说,您可以通过在 log4j 之前调用 System.setOut 来解决它。

    对于静态记录器,它变得更加困难;您可以使用该选项

    -Dlog4j.defaultInitOverride=true
    

    这意味着 log4j 不会自动初始化,但您仍需要安排在第一个记录器之前调用 System.setOut

    欲了解更多信息,请参阅Short introduction to log4j (section Default Initialization Procedure)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多