Skip to content

Commit

Permalink
Enable assertions to be made on LoggingEvents from any thread (#207)
Browse files Browse the repository at this point in the history
The current implementation only verifies against the `LoggingEvent`s captured by the thread that is running the test. `TestLogger` provides access to all events captured across any thread via `TestLogger::getAllLoggingEvents()` so a modifying method has been added to the assertion class to allow the assertion mode to be switched.
  • Loading branch information
topbadger committed Oct 18, 2021
1 parent 565d944 commit 2be2665
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.github.valfirst.slf4jtest;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.assertj.core.api.AbstractAssert;
import uk.org.lidalia.slf4jext.Level;

abstract class AbstractTestLoggerAssert<C extends AbstractAssert<C, TestLogger>>
extends AbstractAssert<C, TestLogger> {
protected Supplier<List<LoggingEvent>> loggingEventsSupplier;

protected AbstractTestLoggerAssert(TestLogger testLogger, Class clazz) {
super(testLogger, clazz);
loggingEventsSupplier = testLogger::getLoggingEvents;
}

protected long getLogCount(Level level, Predicate<LoggingEvent> predicate) {
return actual.getLoggingEvents().stream()
return loggingEventsSupplier.get().stream()
.filter(event -> level.equals(event.getLevel()) && predicate.test(event))
.count();
}
Expand Down
23 changes: 19 additions & 4 deletions src/main/java/com/github/valfirst/slf4jtest/TestLoggerAssert.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,27 @@
/**
* A set of assertions to validate that logs have been logged to a {@link TestLogger}.
*
* <p>Should be thread safe, as this uses <code>testLogger.getLoggingEvents()</code>.
* <p>Should be thread safe, as this uses <code>testLogger.getLoggingEvents()</code> by default. The
* assertion mode can be switched to use <code>testLogger.getAllLoggingEvents()</code> by calling
* {@link #anyThread()}.
*/
public class TestLoggerAssert extends AbstractTestLoggerAssert<TestLoggerAssert> {

protected TestLoggerAssert(TestLogger testLogger) {
super(testLogger, TestLoggerAssert.class);
}

/**
* Changes the assertion mode to verify that log messages have been logged regardless of which
* thread actually logged the message.
*
* @return a {@link TestLoggerAssert} for chaining
*/
public TestLoggerAssert anyThread() {
loggingEventsSupplier = actual::getAllLoggingEvents;
return this;
}

/**
* Verify that a log message, at a specific level, has been logged by the test logger.
*
Expand Down Expand Up @@ -47,7 +60,7 @@ public TestLoggerAssert hasLogged(
* @return a {@link TestLoggerAssert} for chaining
*/
public TestLoggerAssert hasLogged(LoggingEvent event) {
if (!actual.getLoggingEvents().contains(event)) {
if (!loggingEventsSupplier.get().contains(event)) {
failWithMessage("Failed to find %s", event);
}
return this;
Expand Down Expand Up @@ -87,7 +100,7 @@ public TestLoggerAssert hasNotLogged(
* @return a {@link TestLoggerAssert} for chaining
*/
public TestLoggerAssert hasNotLogged(LoggingEvent event) {
if (actual.getLoggingEvents().contains(event)) {
if (loggingEventsSupplier.get().contains(event)) {
failWithMessage("Found %s, even though we expected not to", event);
}
return this;
Expand All @@ -100,6 +113,8 @@ public TestLoggerAssert hasNotLogged(LoggingEvent event) {
* @return the {@link LevelAssert} bound to the given {@link Level}
*/
public LevelAssert hasLevel(Level level) {
return new LevelAssert(actual, level);
LevelAssert levelAssert = new LevelAssert(actual, level);
levelAssert.loggingEventsSupplier = loggingEventsSupplier;
return levelAssert;
}
}
Loading

0 comments on commit 2be2665

Please sign in to comment.