1. ホーム

[解決済み】Loggerのメッセージに対してJUnitアサートを行う方法

2022-04-05 02:15:23

質問

私は、その状態を報告するためにJavaロガーを呼び出すいくつかのテスト中のコードを持っています。 JUnitテストコードでは、このロガーに正しいログエントリが作成されたことを確認したいと思います。次のようなものです。

methodUnderTest(bool x){
    if(x)
        logger.info("x happened")
}

@Test tester(){
    // perhaps setup a logger first.
    methodUnderTest(true);
    assertXXXXXX(loggedLevel(),Level.INFO);
}

特別に適合させたロガー(またはハンドラ、フォーマッタ)を使えば可能だと思いますが、すでに存在するソリューションを再利用することを希望します。(そして、正直なところ、loggerからlogRecordを取得する方法は私には明確ではありませんが、それが可能であるとします)。

どのように解決するのか?

これらの(驚くほど)迅速かつ有用な回答をどうもありがとうございました。

私がこれを使いたいコードベースは、そのロガーメカニズムとしてjava.util.loggingを使います。そして、私は、log4jまたはロガーインターフェース/facadesにそれを完全に変更するためにそれらのコードで十分にくつろいだ感じがしません。 しかし、これらの提案に基づいて、私は、j.u.l.handler拡張を'ハックアップ'しました。

簡単にまとめると以下のようになります。拡張 java.util.logging.Handler :

class LogHandler extends Handler
{
    Level lastLevel = Level.FINEST;

    public Level  checkLevel() {
        return lastLevel;
    }    

    public void publish(LogRecord record) {
        lastLevel = record.getLevel();
    }

    public void close(){}
    public void flush(){}
}

明らかに、あなたが好き/好き/必要なものを好きなだけ LogRecord または、オーバーフローが発生するまで、すべてをスタックにプッシュします。

junit-testの準備では、まず最初に、(1)で作成した java.util.logging.Logger を追加し、そのような新しい LogHandler を追加しました。

@Test tester() {
    Logger logger = Logger.getLogger("my junit-test logger");
    LogHandler handler = new LogHandler();
    handler.setLevel(Level.ALL);
    logger.setUseParentHandlers(false);
    logger.addHandler(handler);
    logger.setLevel(Level.ALL);

の呼び出しは setUseParentHandlers() は、通常のハンドラを黙らせることで、(この junit-test の実行では)不要なログを記録しないようにするためです。 テスト中のコードがこのロガーを使用する必要がある場合は、 テストを実行し、assertEquality を実行してください。

    libraryUnderTest.setLogger(logger);
    methodUnderTest(true);  // see original question.
    assertEquals("Log level as expected?", Level.INFO, handler.checkLevel() );
}

(もちろん、この作業の大部分を @Before メソッドで、その他にもさまざまな改良を加えていますが、それではこのプレゼンテーションの意味がありません)。