使用 assert 测试日志输出,其中 Log 有一些模式配置

问题描述

我正在尝试测试在我的配置文件中排除 HTML 模式的日志的输出。在日志中,我用空格字符替换了 javascript 单词,我想用 assert 语句测试它。

Application.java

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}

ApplicationTest.java

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.read.ListAppender;
import com.testing.test.proj.util.MemoryAppender;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertthat;
@Slf4j
public class ApplicationTest {

@Test
public void testLogging()
{
String[] args = {};
Application.main(args);
assertthat(args).isNotNull();

Logger logger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
logger.addAppender(listAppender);
listAppender.start();

log.info("<html><h1>Testing escape character<h1>");
log.info("<body onload=\"javascript:alert(1)\"/>");
log.info("</html>");

List<ILoggingEvent> logsList = listAppender.list;
System.out.println(logsList.stream()
                       .filter(event -> event.getMessage().contains("javascript") && 
event.getLevel().equals(ch.qos.logback.classic.Level.INFO))
                       .collect(Collectors.toList()));
assertthat(logsList.stream()
    .filter(event -> event.getMessage().contains("javascript"))
    .collect(Collectors.toList()).size()).isEqualTo(0);
}
}

在 logback 配置文件中,我添加一个转换规则来转义 HTML 字符。

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<conversionRule conversionWord="htmlEscapedMessage"
converterClass = 
"com.synchronoss.cloud.vzw.ifttt.util.HtmlEscapedMessageConverter"/>
<appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
  <pattern>%-10(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} - 
   %htmlEscapedMessage %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CON"/>
</root>
</configuration>

HtmlEscapedMessageConverter.java

import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.helpers.Transform;

public class HtmlEscapedMessageConverter extends ClassicConverter {
 public String convert(ILoggingEvent event) {
  return Transform.escapeTags(event.getFormattedMessage());
  }

}

但是在从 ListAppender 打印日志时,我可以看到它无法打印替换的日志,而是打印了我在代码中给出的日志。

输出

2021-01-12 16:18:51.411  INFO [test,] 4068 --- [           main] c.s.cloud.test.proj.Application          : Started Application in 34.547 seconds (JVM running for 36.526)
2021-01-12 16:18:51.536  INFO [test,] 4068 --- [           main] c.s.cloud.test.proj.ApplicationTest      : <html><h1>Testing escape character<h1>
2021-01-12 16:18:51.536  INFO [test,] 4068 --- [           main] c.s.cloud.test.proj.ApplicationTest      : <body onload="alert(1)"/>
2021-01-12 16:18:51.536  INFO [test,] 4068 --- [           main] c.s.cloud.test.proj.ApplicationTest      : </html>
[[INFO] <body onload="javascript:alert(1)"/>]

org.opentest4j.AssertionFailedError: 
Expecting:
<1>
to be equal to:
<0>
but was not.
Expected :0
Actual   :1
<Click to see difference>

如果您可以看到 system.out.println() 输出,那么您会发现它在日志中包含 javascript。 我不确定在使用 ILogging 捕获日志时,logback 配置中的 appender 是如何工作的。 我不确定如何将 appender 添加到 ListAppender 以便它应该获取屏幕上打印的日志。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)