View Javadoc
1   package com.github.valfirst.slf4jtest;
2   
3   import java.util.Objects;
4   import java.util.function.Predicate;
5   import java.util.stream.Collectors;
6   import org.slf4j.event.Level;
7   
8   /**
9    * A set of assertions to validate that logs have been logged to a {@link TestLogger}, for a
10   * specific log level.
11   */
12  public class LevelAssert extends AbstractTestLoggerAssert<LevelAssert> {
13  
14      private static Predicate<LoggingEvent> messageWithSubstring(String substring) {
15          return event -> event.getMessage().contains(substring);
16      }
17  
18      private static Predicate<LoggingEvent> messageForPattern(String regex) {
19          return event -> event.getMessage().matches(regex);
20      }
21  
22      private final Level level;
23  
24      public LevelAssert(TestLogger logger, Level level) {
25          super(logger, LevelAssert.class);
26  
27          this.level = level;
28      }
29  
30      /**
31       * Assert that the given log level has the expected number of logs, regardless of content.
32       *
33       * @param expected the number of logs expected at this level
34       * @return a {@link LevelAssert} for chaining
35       */
36      public LevelAssert hasNumberOfLogs(int expected) {
37          long count = getLogCount(level, ignored -> true);
38          if (count != expected) {
39              failWithMessage(
40                      "Expected level %s to have %d log messages available, but %d were found",
41                      level, expected, count);
42          }
43  
44          return this;
45      }
46  
47      /**
48       * Assert that the given log level includes a log message that contains a substring.
49       *
50       * @param substring a substring of a log message that should be present
51       * @return a {@link LevelAssert} for chaining
52       */
53      public LevelAssert hasMessageContaining(String substring) {
54          long count = getLogCount(level, messageWithSubstring(substring));
55          if (count == 0) {
56              failWithMessage(
57                      "Expected level %s to contain a log message containing `%s`, but it did not.\n\nLog messages found:%n%s",
58                      level, substring, eventsToLogMessage(level));
59          }
60  
61          return this;
62      }
63  
64      /**
65       * Assert that the given log level includes a log message that matches a regex.
66       *
67       * @param regex the regular expression to which this string is to be matched
68       * @return a {@link LevelAssert} for chaining
69       */
70      public LevelAssert hasMessageMatching(String regex) {
71          long count = getLogCount(level, messageForPattern(regex));
72          if (count == 0) {
73              failWithMessage(
74                      "Expected level %s to contain a log message matching regex `%s`, but it did not.\n\nLog messages found:%n%s",
75                      level, regex, eventsToLogMessage());
76          }
77  
78          return this;
79      }
80  
81      @Override
82      public boolean equals(Object o) {
83          if (this == o) {
84              return true;
85          }
86          if (o == null || getClass() != o.getClass()) {
87              return false;
88          }
89          if (!super.equals(o)) {
90              return false;
91          }
92          LevelAssert that = (LevelAssert) o;
93          return level == that.level;
94      }
95  
96      @Override
97      public int hashCode() {
98          return Objects.hash(super.hashCode(), level);
99      }
100 
101     private String eventsToLogMessage() {
102         return loggingEventsSupplier.get().stream()
103                 .map(e -> "- " + e)
104                 .collect(Collectors.joining("\n"));
105     }
106 
107     private String eventsToLogMessage(Level level) {
108         return loggingEventsSupplier.get().stream()
109                 .filter(event -> level.equals(event.getLevel()))
110                 .map(e -> "- " + e)
111                 .collect(Collectors.joining("\n"));
112     }
113 }