Skip to content

Commit 5ab8b69

Browse files
committed
add application, test and the extension
1 parent 16a1f08 commit 5ab8b69

File tree

5 files changed

+284
-0
lines changed

5 files changed

+284
-0
lines changed

pom.xml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>de.doubleslash.assertlog</groupId>
8+
<artifactId>assert-log</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<name>assert-log</name>
12+
13+
<properties>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<maven.compiler.source>11</maven.compiler.source>
16+
<maven.compiler.target>11</maven.compiler.target>
17+
</properties>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>org.apache.logging.log4j</groupId>
22+
<artifactId>log4j-api</artifactId>
23+
<version>2.14.1</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.apache.logging.log4j</groupId>
27+
<artifactId>log4j-core</artifactId>
28+
<version>2.14.1</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.junit.jupiter</groupId>
32+
<artifactId>junit-jupiter</artifactId>
33+
<version>5.7.1</version>
34+
<scope>test</scope>
35+
</dependency>
36+
</dependencies>
37+
38+
<build>
39+
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
40+
<plugins>
41+
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
42+
<plugin>
43+
<artifactId>maven-clean-plugin</artifactId>
44+
<version>3.1.0</version>
45+
</plugin>
46+
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
47+
<plugin>
48+
<artifactId>maven-resources-plugin</artifactId>
49+
<version>3.0.2</version>
50+
</plugin>
51+
<plugin>
52+
<artifactId>maven-compiler-plugin</artifactId>
53+
<version>3.8.0</version>
54+
</plugin>
55+
<plugin>
56+
<artifactId>maven-surefire-plugin</artifactId>
57+
<version>2.22.1</version>
58+
</plugin>
59+
<plugin>
60+
<artifactId>maven-jar-plugin</artifactId>
61+
<version>3.0.2</version>
62+
</plugin>
63+
<plugin>
64+
<artifactId>maven-install-plugin</artifactId>
65+
<version>2.5.2</version>
66+
</plugin>
67+
<plugin>
68+
<artifactId>maven-deploy-plugin</artifactId>
69+
<version>2.8.2</version>
70+
</plugin>
71+
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
72+
<plugin>
73+
<artifactId>maven-site-plugin</artifactId>
74+
<version>3.7.1</version>
75+
</plugin>
76+
<plugin>
77+
<artifactId>maven-project-info-reports-plugin</artifactId>
78+
<version>3.0.0</version>
79+
</plugin>
80+
</plugins>
81+
</pluginManagement>
82+
</build>
83+
</project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package de.doubleslash.app;
2+
3+
import org.apache.logging.log4j.LogManager;
4+
import org.apache.logging.log4j.Logger;
5+
6+
/**
7+
* My great App!
8+
*/
9+
public class App {
10+
11+
private static final Logger LOG = LogManager.getLogger();
12+
13+
/**
14+
* Run the app. Do some logging that we can test using our JUnit Jupiter Extension.
15+
*/
16+
public void run() {
17+
LOG.info("Running");
18+
19+
LOG.warn("We have a situation here...");
20+
21+
try {
22+
doSomethingDangerous();
23+
} catch (Exception e) {
24+
LOG.error(e, e);
25+
}
26+
}
27+
28+
private void doSomethingDangerous() {
29+
throw new IllegalStateException("Something baaad happened!!");
30+
}
31+
32+
}

src/main/resources/log4j2.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Configuration status="WARN">
3+
<Appenders>
4+
<Console name="Console" target="SYSTEM_OUT">
5+
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
6+
</Console>
7+
</Appenders>
8+
<Loggers>
9+
<Root level="info">
10+
<AppenderRef ref="Console"/>
11+
</Root>
12+
</Loggers>
13+
</Configuration>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package de.doubleslash.app;
2+
3+
import static org.apache.logging.log4j.Level.WARN;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.api.extension.RegisterExtension;
7+
8+
import de.doubleslash.assertlog.log4j2.AssertLoggedExtension;
9+
10+
public class AppTest {
11+
12+
private final App app = new App();
13+
14+
@RegisterExtension
15+
static final AssertLoggedExtension assertLogged = new AssertLoggedExtension();
16+
17+
@Test
18+
public void shouldHaveLogged() {
19+
app.run();
20+
21+
assertLogged.info("Running");
22+
}
23+
24+
@Test
25+
void shouldHaveLoggedAlso() {
26+
app.run();
27+
28+
assertLogged.eventMatching(ev -> ev.getLevel() == WARN &&
29+
ev.getMessage().getFormattedMessage().equals("We have a situation here..."));
30+
}
31+
32+
@Test
33+
void shouldHaveLoggedException() {
34+
app.run();
35+
36+
assertLogged.error("java.lang.IllegalStateException: Something baaad happened!!");
37+
}
38+
39+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package de.doubleslash.assertlog.log4j2;
2+
3+
import static java.util.Collections.unmodifiableList;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.function.Predicate;
8+
9+
import org.apache.logging.log4j.Level;
10+
import org.apache.logging.log4j.LogManager;
11+
import org.apache.logging.log4j.core.LogEvent;
12+
import org.apache.logging.log4j.core.Logger;
13+
import org.apache.logging.log4j.core.appender.AbstractAppender;
14+
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
15+
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
16+
import org.junit.jupiter.api.extension.ExtensionContext;
17+
import org.opentest4j.AssertionFailedError;
18+
19+
/**
20+
* JUnit extension to assert log statements for Log4j2.<p>
21+
* Usage Example:
22+
* <pre>
23+
* {@code
24+
*
25+
* @RegisterExtension
26+
* AssertLoggedExtension assertLogged = new AssertLoggedExtension();
27+
*
28+
* MyApp testee = new MyApp();
29+
*
30+
* @Test
31+
* public void shouldHaveLogged() {
32+
* testee.run();
33+
*
34+
* assertLogged.info("Running");
35+
* }
36+
* }
37+
* </pre>
38+
*/
39+
public class AssertLoggedExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {
40+
41+
private final ListAppender listAppender = new ListAppender();
42+
43+
@Override
44+
public void beforeTestExecution(ExtensionContext context) {
45+
Logger rootLogger = (Logger) LogManager.getRootLogger();
46+
rootLogger.addAppender(listAppender);
47+
}
48+
49+
@Override
50+
public void afterTestExecution(ExtensionContext context) {
51+
Logger rootLogger = (Logger) LogManager.getRootLogger();
52+
rootLogger.removeAppender(listAppender);
53+
listAppender.clearLogEvents();
54+
}
55+
56+
public void trace(String expectecMessage) {
57+
assertLogged(expectecMessage, Level.TRACE);
58+
}
59+
60+
public void debug(String expectedMessage) {
61+
assertLogged(expectedMessage, Level.DEBUG);
62+
}
63+
64+
public void info(String expectedMessage) {
65+
assertLogged(expectedMessage, Level.INFO);
66+
}
67+
68+
public void warn(String expectedMessage) {
69+
assertLogged(expectedMessage, Level.WARN);
70+
}
71+
72+
public void error(String expectedMessage) {
73+
assertLogged(expectedMessage, Level.ERROR);
74+
}
75+
76+
public void eventMatching(Predicate<LogEvent> logEventPredicate) {
77+
listAppender.getLoggedEvents().stream()
78+
.filter(logEventPredicate)
79+
.findAny()
80+
.orElseThrow(() -> new AssertionFailedError("Log message matching predicate was expected, but not logged."));
81+
}
82+
83+
private void assertLogged(String message, Level level) {
84+
listAppender.getLoggedEvents().stream()
85+
.filter(e -> e.getLevel().equals(level))
86+
.filter(e -> e.getMessage().getFormattedMessage().equals(message))
87+
.findAny()
88+
.orElseThrow(() -> new AssertionFailedError("Log message '" + message + "' with level '" + level + "' was expected, but not logged."));
89+
}
90+
91+
}
92+
93+
/**
94+
* An appender that captures all received events in a list.
95+
*/
96+
class ListAppender extends AbstractAppender {
97+
98+
private final List<LogEvent> events = new ArrayList<>();
99+
100+
protected ListAppender() {
101+
super("ListAppender", null, null, false, null);
102+
setStarted();
103+
}
104+
105+
@Override
106+
public void append(LogEvent event) {
107+
events.add(event.toImmutable());
108+
}
109+
110+
public List<LogEvent> getLoggedEvents() {
111+
return unmodifiableList(events);
112+
}
113+
114+
public void clearLogEvents() {
115+
events.clear();
116+
}
117+
}

0 commit comments

Comments
 (0)