カスタム例外のレイアウトを内部的に変更しようとしています。これを単体テストするために、コンソール出力をキャプチャしようとしています。以前にコンソール出力をキャプチャしたことがありますが、以前に使用した方法では、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();
consoleOutput は空です。ConsoleAppender の javadoc を見ると、次のように表示されます。
デフォルトのターゲットは System.out です。
次の行だけを含めるようにコードを変更した場合:
LOGGER.debug("Simple message");
コンソールに期待される結果が表示されます。
2013-06-02 19:49:46,818 DEBUG [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 を静的にしたい場合はあまり良くありません。なぜこれが起こるのか、ロガーをこのように宣言せずに元の質問に対処する方法はありますか?