當運行單元測試時,我想在測試錯誤級別消息的過程中失敗。使用SLF4J/Logback實現這個最簡單的方法是什麼?我想避免編寫自己的ILoggerFactory實現。在錯誤級別日誌事件中使Logback引發異常
我試過編寫一個自定義的Appender,但是我不能通過調用Appender的代碼來傳播異常,Appender的所有異常都會被抓到。
當運行單元測試時,我想在測試錯誤級別消息的過程中失敗。使用SLF4J/Logback實現這個最簡單的方法是什麼?我想避免編寫自己的ILoggerFactory實現。在錯誤級別日誌事件中使Logback引發異常
我試過編寫一個自定義的Appender,但是我不能通過調用Appender的代碼來傳播異常,Appender的所有異常都會被抓到。
因此,如果調用記錄器的任何錯誤報告消息,您希望失敗測試用例。
記錄框架通常設計爲不會向用戶拋出任何異常。另一種選擇(除了Raedwald的回答)將創建一個自定義appender,當記錄ERROR消息時將靜態布爾標誌設置爲true,在安裝方法中重置此標誌並在拆卸方法中檢查它(或者創建JUnit規則重置/檢查標誌)。
關鍵是寫一個自定義的appender。你不會說你使用了哪個單元測試框架,但是對於JUnit我需要做類似的事情(它比一切錯誤稍微複雜一點,但基本上是相同的概念),並且創建了一個JUnit @Rule來添加我的appender ,並且appender根據需要未通過測試。
我把我的代碼,這個答案在公共領域:
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.rules.ExternalResource;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.fail;
/**
* A JUnit {@link org.junit.Rule} which attaches itself to Logback, and fails the test if an error is logged.
* Designed for use in some tests, as if the system would log an error, that indicates that something
* went wrong, even though the error was correctly caught and logged.
*/
public class FailOnErrorLogged extends ExternalResource {
private FailOnErrorAppender appender;
@Override
protected void before() throws Throwable {
super.before();
final LoggerContext loggerContext = (LoggerContext)(LoggerFactory.getILoggerFactory());
final Logger rootLogger = (Logger)(LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME));
appender = new FailOnErrorAppender();
appender.setContext(loggerContext);
appender.start();
rootLogger.addAppender(appender);
}
@Override
protected void after() {
appender.stop();
final Logger rootLogger = (Logger)(LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME));
rootLogger.detachAppender(appender);
super.after();
}
private static class FailOnErrorAppender extends AppenderBase<ILoggingEvent> {
@Override
protected void append(final ILoggingEvent eventObject) {
if (eventObject.getLevel().isGreaterOrEqual(Level.ERROR)) {
fail("Error logged: " + eventObject.getFormattedMessage());
}
}
}
}
用法的例子:
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExampleTest {
private static final Logger log = LoggerFactory.getLogger(ExampleTest.class);
@Rule
public FailOnErrorLogged failOnErrorLogged = new FailOnErrorLogged();
@Test
public void testError() {
log.error("Test Error");
}
@Test
public void testInfo() {
log.info("Test Info");
}
}
的方法是testError失敗並testInfo方法傳遞。如果測試調用記錄錯誤的真正測試類,它的工作原理也是一樣的。