From 72d46791e84b85191cc5e312fc480b95d7cf8f5d Mon Sep 17 00:00:00 2001 From: Daniel Flassak Date: Thu, 12 Mar 2020 11:22:27 +0100 Subject: [PATCH 1/6] use JUnit 5 instead of JUnit 4 --- pom.xml | 11 ++++-- .../infrastructure/logcapture/LogCapture.java | 27 ++++++------- .../CapturingAppenderIntegrationTest.java | 8 ++-- .../logcapture/ExpectedMdcEntryUnitTest.java | 8 ++-- .../logcapture/LogCaptureTest.java | 38 +++++++++---------- 5 files changed, 45 insertions(+), 47 deletions(-) diff --git a/pom.xml b/pom.xml index 9aef0b3..1964bbc 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ 1.8 1.18.10 1.2.3 - 4.12 + 5.6.0 UTF-8 3.14.0 @@ -61,8 +61,13 @@ ${logback.version} - junit - junit + org.junit.jupiter + junit-jupiter-api + ${junit.version} + + + org.junit.jupiter + junit-jupiter-engine ${junit.version} diff --git a/src/main/java/de/dm/infrastructure/logcapture/LogCapture.java b/src/main/java/de/dm/infrastructure/logcapture/LogCapture.java index 3300f9d..82c4359 100644 --- a/src/main/java/de/dm/infrastructure/logcapture/LogCapture.java +++ b/src/main/java/de/dm/infrastructure/logcapture/LogCapture.java @@ -3,9 +3,9 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import lombok.RequiredArgsConstructor; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; import org.slf4j.LoggerFactory; import java.util.Arrays; @@ -16,7 +16,7 @@ /** * a JUnit 4 @Rule that can be used to capture log output. Use the appropriate constructor for unit/integration tests. */ -public final class LogCapture implements TestRule { //should implement AfterEachCallback, BeforeEachCallback in JUnit 5 +public final class LogCapture implements BeforeEachCallback, AfterEachCallback { //should implement AfterEachCallback, BeforeEachCallback in JUnit 5 final Set capturedPackages; private CapturingAppender capturingAppender; @@ -59,18 +59,13 @@ private LogCapture(Set capturedPackages) { } @Override - public Statement apply(Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - addAppenderAndSetLogLevelToDebug(); - try { - base.evaluate(); - } finally { - removeAppenderAndResetLogLevel(); - } - } - }; + public void beforeEach(ExtensionContext context) { + addAppenderAndSetLogLevelToDebug(); + } + + @Override + public void afterEach(ExtensionContext context) { + removeAppenderAndResetLogLevel(); } /** diff --git a/src/test/java/de/dm/infrastructure/logcapture/CapturingAppenderIntegrationTest.java b/src/test/java/de/dm/infrastructure/logcapture/CapturingAppenderIntegrationTest.java index 14a4955..896b6a8 100644 --- a/src/test/java/de/dm/infrastructure/logcapture/CapturingAppenderIntegrationTest.java +++ b/src/test/java/de/dm/infrastructure/logcapture/CapturingAppenderIntegrationTest.java @@ -1,7 +1,7 @@ package de.dm.infrastructure.logcapture; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; @@ -21,12 +21,12 @@ public void containsMdcEntries() { mdcContents.put(TEST_KEY, "this is a test value, cool!"); mdcContents.put(OTHER_KEY, "this is a good value, cool!"); - Assert.assertTrue(CapturingAppender.containsMdcEntries(mdcContents, expectedMdcEntries)); + Assertions.assertTrue(CapturingAppender.containsMdcEntries(mdcContents, expectedMdcEntries)); } @Test public void nullEntriesShouldNotThrowNullPointerException() { Map mdcContents = new HashMap<>(); - Assert.assertTrue(CapturingAppender.containsMdcEntries(mdcContents, null)); + Assertions.assertTrue(CapturingAppender.containsMdcEntries(mdcContents, null)); } } diff --git a/src/test/java/de/dm/infrastructure/logcapture/ExpectedMdcEntryUnitTest.java b/src/test/java/de/dm/infrastructure/logcapture/ExpectedMdcEntryUnitTest.java index 90812f5..879e919 100644 --- a/src/test/java/de/dm/infrastructure/logcapture/ExpectedMdcEntryUnitTest.java +++ b/src/test/java/de/dm/infrastructure/logcapture/ExpectedMdcEntryUnitTest.java @@ -1,7 +1,7 @@ package de.dm.infrastructure.logcapture; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; @@ -15,7 +15,7 @@ public void isContainedIn() { ExpectedMdcEntry expectedMdcEntry = ExpectedMdcEntry.withMdc(TEST_KEY, "test value"); Map mdcContents = new HashMap<>(); mdcContents.put(TEST_KEY, "this is a test value, cool!"); - Assert.assertTrue(expectedMdcEntry.isContainedIn(mdcContents)); + Assertions.assertTrue(expectedMdcEntry.isContainedIn(mdcContents)); } @Test @@ -24,7 +24,7 @@ public void isNotContainedIn() { Map mdcContents = new HashMap<>(); mdcContents.put(TEST_KEY, "this is a value, cool!"); mdcContents.put("some_other_key", "this is a test value, cool!"); - Assert.assertFalse(expectedMdcEntry.isContainedIn(mdcContents)); + Assertions.assertFalse(expectedMdcEntry.isContainedIn(mdcContents)); } } diff --git a/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java b/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java index 3703efc..1a69c6b 100644 --- a/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java +++ b/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java @@ -3,9 +3,9 @@ import ch.qos.logback.classic.Level; import com.example.app.LogCaptureCreatorInOtherPackage; import lombok.extern.slf4j.Slf4j; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -18,12 +18,9 @@ @Slf4j public class LogCaptureTest { - @Rule + @RegisterExtension public LogCapture logCapture = LogCapture.forPackages("de.dm", "com.capture"); - @Rule //to be replaced with Assertions.assertThrows() in JUnit 5 - public final ExpectedException exception = ExpectedException.none(); - @Test public void twoLogMessagesInOrder() { log.info("something interesting"); @@ -57,14 +54,14 @@ public void captureLogsForMultiplePackages() { @Test public void twoLogMessagesOutOfOrder() { - log.error("something terrible"); - log.info("something interesting"); - - exception.expect(AssertionError.class); + Assertions.assertThrows(AssertionError.class, () -> { + log.error("something terrible"); + log.info("something interesting"); - logCapture - .assertLogged(Level.INFO, "^something interesting") - .thenLogged(Level.ERROR, "terrible"); + logCapture + .assertLogged(Level.INFO, "^something interesting") + .thenLogged(Level.ERROR, "terrible"); + }); } @Test @@ -84,12 +81,13 @@ public void catchMissingLogMessage() { @Test public void filterOutIrrelevantLogMessagesInIntegrationTest() { - ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); - rootLogger.getLoggerContext().getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME).setLevel(DEBUG); - Logger logger = LoggerFactory.getLogger("com.acme.whatever"); - logger.info("something from another package"); - exception.expect(AssertionError.class); - logCapture.assertLogged(Level.INFO, "something from another package"); + Assertions.assertThrows(AssertionError.class, () -> { + ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); + rootLogger.getLoggerContext().getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME).setLevel(DEBUG); + Logger logger = LoggerFactory.getLogger("com.acme.whatever"); + logger.info("something from another package"); + logCapture.assertLogged(Level.INFO, "something from another package"); + }); } @Test From 97ef2e2ff6e29ac24818736293833b64291b91c0 Mon Sep 17 00:00:00 2001 From: Daniel Flassak Date: Mon, 16 Mar 2020 11:04:43 +0100 Subject: [PATCH 2/6] add test for forCurrentPackage() --- .../logcapture/LogCaptureTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java b/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java index 1a69c6b..130dadd 100644 --- a/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java +++ b/src/test/java/de/dm/infrastructure/logcapture/LogCaptureTest.java @@ -21,6 +21,9 @@ public class LogCaptureTest { @RegisterExtension public LogCapture logCapture = LogCapture.forPackages("de.dm", "com.capture"); + @RegisterExtension + public LogCapture logCaptureForCurrentPackage = LogCapture.forCurrentPackage(); + @Test public void twoLogMessagesInOrder() { log.info("something interesting"); @@ -38,6 +41,21 @@ public void captureMultilineMessages() { logCapture.assertLogged(Level.INFO, "something interesting"); } + @Test + public void captureLogsForCurrentPackage() { + log.info("Hello from logcapture"); + + final Logger acmeLogger = LoggerFactory.getLogger("com.acme"); + acmeLogger.info("Hello from com.acme"); + + logCaptureForCurrentPackage + .assertLogged(INFO, "^Hello from logcapture$"); + + Assertions.assertThrows(AssertionError.class, () -> { + logCaptureForCurrentPackage.assertLogged(INFO, "Hello from com.acme"); + }); + } + @Test public void captureLogsForMultiplePackages() { log.info("something interesting"); From 9ade59f7e155888420a7a28c4de9d8c95f8753ea Mon Sep 17 00:00:00 2001 From: Daniel Flassak Date: Mon, 16 Mar 2020 11:05:34 +0100 Subject: [PATCH 3/6] update Readme for 3.0.0 --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index aefd714..1a08e9c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [](https://dmtech.de/) [![Build Status](https://travis-ci.org/dm-drogeriemarkt/log-capture.svg?branch=master)](https://travis-ci.org/dm-drogeriemarkt/log-capture) -Helper for Unit/Integration tests with JUnit 4 to test if something has been logged. +Helper for Unit/Integration tests with JUnit 4/5 to test if something has been logged. Because this is a library, Checkstyle is used to make sure all public classes/methods have appropriate Javadoc. @@ -24,6 +24,15 @@ Because this is a library, Checkstyle is used to make sure all public classes/me ## Changes +### 3.0.0 + +Updated from JUnit 4 to JUnit 5. + +Tu update from 2.x.x to 3.x.x: + +* Use JUnit 5 instead of JUnit 4 +* Replace `@Rule` in logging tests with `@RegisterExtension` + ### 2.0.1 Fixed a bug where multiline log messages (for example Messages that contain a stack trace) could not be matched. @@ -37,6 +46,12 @@ Fixed a bug where multiline log messages (for example Messages that contain a st ## Usage +### Junit 4 vs 5 + +If you still use Junit 4, you need to use LogCapture 2.x.x + +There is no guarantee, however, if and how long 2.x.x will be maintained. We plan to maintain it as long as it is needed, though. + ### Maven Add log-capture as a test dependency to your project. If you use Maven, add this to your pom.xml: @@ -45,7 +60,7 @@ Add log-capture as a test dependency to your project. If you use Maven, add this de.dm.infrastructure log-capture - 2.0.1 + 3.0.0 test ``` @@ -64,7 +79,7 @@ public class MyUnitTest { Logger logger = LoggerFactory.getLogger(MyUnitTest.class); - @Rule + @RegisterExtension //use @Rule for LogCapture 2/JUnit 4 public LogCapture logCapture = LogCapture.forCurrentPackage(); @Test @@ -94,7 +109,7 @@ public class MyIntegrationTest { Logger logger = LoggerFactory.getLogger(MyIntegrationTest.class); // captures only logs from my.company and utility.that.logs and sub-packages - @Rule + @RegisterExtension //use @Rule for LogCapture 2/JUnit 4 public LogCapture logCapture = LogCapture.forPackages("my.company", "utility.that.logs"); @Test @@ -127,7 +142,7 @@ import static de.dm.prom.logcapture.ExpectedMdcEntry.withMdc; public class MyUnitTest { Logger logger = LoggerFactory.getLogger(MyUnitTest.class); - @Rule + @RegisterExtension public LogCapture logCapture = LogCapture.forCurrentPackage(); @Test From 1fc704588079e2aa7754d578bccd82d64f3a55e5 Mon Sep 17 00:00:00 2001 From: Daniel Flassak Date: Mon, 16 Mar 2020 12:10:08 +0100 Subject: [PATCH 4/6] update dependencies --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 1964bbc..8855d50 100644 --- a/pom.xml +++ b/pom.xml @@ -30,18 +30,18 @@ 1.8 - 1.18.10 + 1.18.12 1.2.3 5.6.0 UTF-8 - 3.14.0 - 8.29 + 3.15.0 + 8.30 0.8.5 2.22.2 - 3.1.0 - 3.1.0 - 3.1.1 + 3.1.1 + 3.2.1 + 3.2.0 3.8.1 2.5.3 1.6 From b16cbd4f1f23864e7420d4eb1ca05283b0f49860 Mon Sep 17 00:00:00 2001 From: Daniel Flassak Date: Mon, 16 Mar 2020 12:21:17 +0100 Subject: [PATCH 5/6] add rules for mvn versions:update-properties --- rules.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 rules.xml diff --git a/rules.xml b/rules.xml new file mode 100644 index 0000000..73c0d0d --- /dev/null +++ b/rules.xml @@ -0,0 +1,17 @@ + + + + + (?i).*Alpha(?:-?\d+)? + (?i).*a(?:-?\d+)? + (?i).*Beta(?:-?\d+)? + (?i).*-B(?:-?\d+)? + (?i).*RC(?:-?\d+)? + (?i).*CR(?:-?\d+)? + (?i).*M(?:-?\d+)? + + + + From 87f1f03c0087e5af703e5085226010f7d706b902 Mon Sep 17 00:00:00 2001 From: Daniel Flassak Date: Mon, 16 Mar 2020 12:22:36 +0100 Subject: [PATCH 6/6] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a08e9c..6915a5f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Because this is a library, Checkstyle is used to make sure all public classes/me Updated from JUnit 4 to JUnit 5. -Tu update from 2.x.x to 3.x.x: +To update from 2.x.x to 3.x.x: * Use JUnit 5 instead of JUnit 4 * Replace `@Rule` in logging tests with `@RegisterExtension`