[英]How to write a unit test for a custom logger in log4j2
我創建了幾個自定義記錄器,它們的某些級別覆蓋了 Log4J2 中的自定義記錄器。 我遵循了http://logging.apache.org/log4j/2.x/manual/customloglevels.html 上的指南。
我需要創建一些單元測試來驗證事件是否在正確的自定義級別和配置上注冊。
我感謝任何關於如何開始的提示。 非常感謝。
在這里,您擁有我在其中一項 JUnit 測試中所做的工作。
1- 創建一個自定義 appender,在內存中保存消息列表。
package com.example.appender;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
/**
* @author carrad
*
*/
@Plugin(name = "TestAppender", category = "Core", elementType = "appender", printObject = true)
public class TestAppender extends AbstractAppender {
@Getter
private final List<LogEvent> messages = new ArrayList<>();
protected TestAppender(String name, Filter filter, Layout<? extends Serializable> layout) {
super(name, filter, layout, true, Property.EMPTY_ARRAY);
}
@Override
public void append(LogEvent event) {
messages.add(event);
}
@PluginFactory
public static TestAppender createAppender(
@PluginAttribute("name") String name,
@PluginElement("Layout") Layout<? extends Serializable> layout,
@PluginElement("Filter") final Filter filter,
@PluginAttribute("otherAttribute") String otherAttribute
) {
if (name == null) {
LOGGER.error("No name provided for TestAppender");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new TestAppender(name, filter, layout);
}
}
2- 將 appender 添加到log4j2-test.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" packages="com.example.appender">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<TestAppender name="TestAppender" >
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</TestAppender>
</Appenders>
<Loggers>
<Logger name="com.example" level="All" />
<Root>
<AppenderRef ref="Console" level="All" />
<AppenderRef ref="TestAppender" level="All" />
</Root>
</Loggers>
</Configuration>
3- 在 Junit 測試中獲取對 appender 的引用。
public class LoggingInterceptorTest {
@Autowired // Whatever component you want to test
private InterceptedComponent helperComponent;
private TestAppender appender;
@Before
public void setUp() {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
appender = (TestAppender) config.getAppenders().get("TestAppender");
}
@Test
public void test_wrapping() {
helperComponent.doStuff("437");
Assert.assertEquals(appender.getMessages().size(), 2);
}
}
在您的測試用例中,您可以檢查寫入的消息數量或包含您想要的消息的列表,包括級別等元信息。
我建議查看 log4j2 中的 JUnit 測試。
許多 log4j2 單元測試使用一個 FileAppender 和immediateFlush=true,然后讀入文件並檢查輸出中是否存在一些預期的字符串。 其他人配置一個(org.apache.logging.log4j.test.appender.)ListAppender(這個類位於核心測試jar中)並直接從列表中獲取LogEvent對象。
您可能需要為 log4j2 JUnit 測試創建一個新進程,以確保之前的某個進程尚未加載不同的配置。
一種選擇是使用自定義的 OutputStreamAppender 子類將記錄器配置為寫入內存中的字符串(字節數組)流,您必須對其進行編碼。
然后,您可以對測試中的結果字符串使用斷言。
我最近在這里發表了一篇關於這樣做的博客文章。 也許它會幫助你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.