diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml
index 951909b36f..b467b3c503 100644
--- a/testing-modules/pom.xml
+++ b/testing-modules/pom.xml
@@ -33,6 +33,7 @@
selenium-junit-testng
spring-testing
test-containers
+ testing-assertions
testng
junit-5-basics
easymock
diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml
new file mode 100644
index 0000000000..0a7c4b0860
--- /dev/null
+++ b/testing-modules/testing-assertions/pom.xml
@@ -0,0 +1,28 @@
+
+ 4.0.0
+ testing-assertions
+ 0.0.1-SNAPSHOT
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../../parent-java
+
+
+
+
+ ch.qos.logback
+ logback-classic
+ 1.2.3
+
+
+ org.assertj
+ assertj-core
+ 3.15.0
+ test
+
+
+
diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java
new file mode 100644
index 0000000000..86cd38824c
--- /dev/null
+++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/junit/log/BusinessWorker.java
@@ -0,0 +1,16 @@
+package com.baeldung.junit.log;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BusinessWorker {
+ private static Logger LOGGER = LoggerFactory.getLogger(BusinessWorker.class);
+
+ public void generateLogs(String msg) {
+ LOGGER.trace(msg);
+ LOGGER.debug(msg);
+ LOGGER.info(msg);
+ LOGGER.warn(msg);
+ LOGGER.error(msg);
+ }
+}
diff --git a/testing-modules/testing-assertions/src/main/resources/logback.xml b/testing-modules/testing-assertions/src/main/resources/logback.xml
new file mode 100644
index 0000000000..d485da62ff
--- /dev/null
+++ b/testing-modules/testing-assertions/src/main/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/junit/log/BusinessWorkerUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/junit/log/BusinessWorkerUnitTest.java
new file mode 100644
index 0000000000..9200caf13d
--- /dev/null
+++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/junit/log/BusinessWorkerUnitTest.java
@@ -0,0 +1,48 @@
+package com.baeldung.junit.log;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+
+public class BusinessWorkerUnitTest {
+ private static MemoryAppender memoryAppender;
+ private static final String LOGGER_NAME = "com.baeldung.junit.log";
+ private static final String MSG = "This is a test message!!!";
+
+ @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();
+
+ }
+
+ @After
+ public void cleanUp() {
+ memoryAppender.reset();
+ memoryAppender.stop();
+ }
+
+ @Test
+ public void test() {
+ BusinessWorker worker = new BusinessWorker();
+ worker.generateLogs(MSG);
+
+ // I check that I only have 4 messages (all but trace)
+ assertThat(memoryAppender.countEventsForLogger(LOGGER_NAME)).isEqualTo(4);
+ // I look for a specific message at a specific level, and I only have 1
+ assertThat(memoryAppender.search(MSG, Level.INFO).size()).isEqualTo(1);
+ // I check that the entry that is not present is the trace level
+ assertThat(memoryAppender.contains(MSG, Level.TRACE)).isFalse();
+ }
+}
diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/junit/log/MemoryAppender.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/junit/log/MemoryAppender.java
new file mode 100644
index 0000000000..31c5c69766
--- /dev/null
+++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/junit/log/MemoryAppender.java
@@ -0,0 +1,51 @@
+package com.baeldung.junit.log;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.read.ListAppender;
+
+/**
+ * In memory slf4j appender
+ * Convenient appender to be able to check slf4j invocations
+ */
+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() {
+ return this.list.size();
+ }
+
+ public List getLoggedEvents() {
+ return Collections.unmodifiableList(this.list);
+ }
+}
diff --git a/testing-modules/testing-assertions/src/test/resources/logback.xml b/testing-modules/testing-assertions/src/test/resources/logback.xml
new file mode 100644
index 0000000000..980ce897ff
--- /dev/null
+++ b/testing-modules/testing-assertions/src/test/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file