1.介绍
在本教程中,我们将看看如何我们可以涵盖JUnit测试中生成的日志。
我们将使用它SLF4J-API.和logback执行和创建我们可以用于日志断言的自定义附加程序。
2.Maven的依赖关系
在我们开始之前,让我们添加logback依赖。因为它本地实现了SLF4J-API.,它被自动下载并通过Maven传递性注入到项目中:
<依赖> < groupId > ch.qos。logback logback-classic . 1.2.3
AssertJ在测试时提供非常有用的函数,所以让我们把它的依赖关系也添加到项目中:
<依赖项> org.assertj groupID> ASSERTJ-CORE ARTIFACTID> 3.15.0 version> test scope> 依赖项>
3.A基本业务功能
现在,让我们创建一个将生成日志的对象,我们可以基于测试。
我们的商业工作者对象将只公开一个方法。这个方法将为每个日志级别生成具有相同内容的日志。虽然这个方法在现实世界中不是很有用,但它将很好地用于我们的测试目的:
公共类商人{私有静态记录器Logger = loggerFactory.getLogger(BusinessWorker.class);公共void generatelogs(String msg){logger.trace(msg);logger.debug(msg);logger.info(msg);logger.warn(msg);logger.Error(MSG);}}
4.测试日志
我们想生成log,我们来创建alogback.xml.文件SRC /测试/资源文件夹。让我们保持简单,并将所有日志重定向到a安慰appender:
< ?xml version = " 1.0 " encoding = " utf - 8 " ?> <布局。PatternLayout”> <模式> % d {HH: mm: ss。SSS} [%t] %-5level %logger{36} - %msg%n
4.1。MemoryAppender
现在,我们来创建自定义Appender保留记录内存。我们会扩展ListAppender < ILoggingEvent >那logback提供了,我们将用一些有用的方法充实它:
public class MemoryAppender extends ListAppender {public void reset() {this.list.clear();} public boolean contains(String String, Level Level) {return this.list.stream() .anyMatch(event -> event. getmessage ().toString().contains(String) && event. getlevel ().equals(Level));} public int countEventsForLogger(String loggerName) {return (int) this.list.stream() .filter(event -> event. getloggername ().contains(loggerName)) .count();} public List search(String String) {return this.list.stream() .filter(event -> event. getmessage ().toString().contains(String)) .collect(Collectors.toList());} public List search(String String, Level Level) {return this.list.stream() .filter(event -> event. getmessage ().toString().contains(String) && event. getlevel ().equals(Level)) .collect(Collectors.toList());} public int getSize(){返回this.list.size();} public List getLoggedEvents() {return Collections.unmodifiableList(this.list);}}
的MemoryAppender班级手柄A.列表由日志记录系统自动填充。
它公开了各种各样的方法,以覆盖广泛的测试目的:
- 重启()- 清除列表
- 包含(味精、级别)——返回真的仅当列表包含ILoggingEvent匹配指定的内容和严重性级别
- countEventForLoggers (loggerName)- 返回的数量ILoggingEvent由指定记录器生成
- 搜索(味精)- 返回A.列表的ILoggingEvent匹配特定内容
- 搜索(味精、水平)- 返回A.列表的ILoggingEvent匹配指定的内容和严重性级别
- getsize()- 返回的数量ILoggingEvent年代
- getloggedevents()对象的不可修改视图ILoggingEvent元素
4.2。单元测试
接下来,让我们为业务操作者创建一个JUnit测试。
我们会宣布我们的MemoryAppender作为一个字段,并以编程方式将其注入日志系统。然后,我们将启动appender。
对于我们的测试,我们将设置水平为调试:
@Before public void setup() {Logger Logger = (Logger) LoggerFactory.getLogger(LOGGER_NAME);memoryAppender = new memoryAppender ();memoryAppender.setContext ((LoggerContext) LoggerFactory.getILoggerFactory ());logger.setLevel (Level.DEBUG);logger.addAppender (memoryAppender);memoryAppender.start ();}
现在我们可以创建一个简单的测试,我们实例化我们的商业工作者班级并打电话给generateLogs方法。然后,我们可以在它生成的日志上进行断言:
@test public void test(){businessworker worker = new businessworker();工人.generatelogs(msg);assertthat(moderappender.counteventsforlogger(logger_name))。isequalto(4);asserthat(MemoryPedender.Search(MSG,Level.Info).size())。isequalto(1);assertthat(modentemender.contains(msg,level.trace))。Isfalse();}
此测试使用三个特征MemoryAppender:
- 已经生成了4个日志—每个严重程度应有一个条目,并过滤了跟踪级别
- 只有一个带有内容的日志条目信息随着级别的严重程度信息
- 内容没有日志条目信息和严重程度痕迹
如果我们计划在生成大量日志时在同一个测试类中使用这个类的同一个实例,那么内存使用量将会慢慢增加。我们可以调用MemoryAppender.clear ()在每个测试之前的方法到释放内存并避免OutofMemoryException。
在本例中,我们将保留的日志的范围缩小为LOGGER_NAME包裹,我们定义为“com.金宝搏188体育baeldung.junit.log”。我们可以保留所有的日志loggerfactory.getlogger(logger.root_logger_name),但我们应该尽可能避免这种情况,因为它会消耗大量内存。
5.结论
通过本教程,我们已经证明了如何在我们的单元测试中覆盖日志生成。
与往常一样,可以找到代码在github上。