TestLoggingEventBuilder.java
package com.github.valfirst.slf4jtest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.Marker;
import org.slf4j.event.DefaultLoggingEvent;
import org.slf4j.event.KeyValuePair;
import org.slf4j.event.Level;
import org.slf4j.event.LoggingEvent;
import org.slf4j.helpers.CheckReturnValue;
import org.slf4j.spi.DefaultLoggingEventBuilder;
import org.slf4j.spi.LoggingEventBuilder;
/**
* A {@link LoggingEventBuilder} which changes the following compared to {@link
* DefaultLoggingEventBuilder}:
*
* <ul>
* <li>The {@link #toLoggingEvent} method is added to build the event without logging it.
* <li>The return type of the fluent methods is {@link TestLoggingEventBuilder}. This allows
* {@link #toLoggingEvent} to be used in a fluent manner.
* <li>The {@link KeyValuePair} implementation overrides the {@link Object#equals} and {@link
* Object#hashCode} methods. This allows tests for equality in test assertions.
* </ul>
*/
public class TestLoggingEventBuilder extends DefaultLoggingEventBuilder {
public TestLoggingEventBuilder(Logger logger, Level level) {
super(logger, level);
loggingEvent = new TestLoggingEvent(level, logger);
}
/** Build the event, without logging it. */
public LoggingEvent toLoggingEvent() {
return loggingEvent;
}
static class TestLoggingEvent extends DefaultLoggingEvent {
private List<KeyValuePair> keyValuePairs = null;
public TestLoggingEvent(Level level, Logger logger) {
super(level, logger);
}
@Override
public void addKeyValue(String key, Object value) {
if (keyValuePairs == null) {
keyValuePairs = new ArrayList<>();
}
keyValuePairs.add(new TestKeyValuePair(key, value));
}
@Override
public List<KeyValuePair> getKeyValuePairs() {
return keyValuePairs;
}
}
/**
* Extension of {@link KeyValuePair} with overridden {@link Object#equals} and {@link
* Object#hashCode} methods. This class must be used on the left hand side of {@link
* Object#equals} instead of {@link KeyValuePair}. {@link KeyValuePair} can be used on the right
* hand side.
*/
public static class TestKeyValuePair extends KeyValuePair {
public TestKeyValuePair(String key, Object value) {
super(key, value);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof KeyValuePair)) {
return false;
}
KeyValuePair that = (KeyValuePair) o;
return Arrays.deepEquals(new Object[] {key, value}, new Object[] {that.key, that.value});
}
@Override
public int hashCode() {
return Arrays.deepHashCode(new Object[] {key, value});
}
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder setCause(Throwable cause) {
return (TestLoggingEventBuilder) super.setCause(cause);
}
@CheckReturnValue
@Override
public TestLoggingEventBuilder addMarker(Marker marker) {
return (TestLoggingEventBuilder) super.addMarker(marker);
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder addArgument(Object p) {
return (TestLoggingEventBuilder) super.addArgument(p);
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
return (TestLoggingEventBuilder) super.addArgument(objectSupplier);
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder addKeyValue(String key, Object value) {
return (TestLoggingEventBuilder) super.addKeyValue(key, value);
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder addKeyValue(String key, Supplier<Object> valueSupplier) {
return (TestLoggingEventBuilder) super.addKeyValue(key, valueSupplier);
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder setMessage(String message) {
return (TestLoggingEventBuilder) super.setMessage(message);
}
@CheckReturnValue
@Override
@SuppressWarnings("unchecked")
public TestLoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
return (TestLoggingEventBuilder) super.setMessage(messageSupplier);
}
}