Tinylog writer with a mock instance backed by Mockito.
Warning
This library does not support parallel test execution.
Unlike the traditional approach where each class or even instance has its own named logger, tinylog uses a singleton logger. Keep this in mind when testing logger calls.
Just put a test dependency to your POM:
<dependency>
<artifactId>mock-loggers-tinylog-writer</artifactId>
<groupId>io.github.vitalijr2.logging</groupId>
<scope>test</scope>
<version>1.1.1</version>
</dependency>
Use the MockTinylogWriter
annotation to access the mock writer.
The simplest usage example looks like this:
@MockTinylogWriter
private static Writer writer;
@Test
void helloWorld() {
var helloService = new HelloService();
assertDoesNotThrow(helloService::sayHelloWorld);
verify(writer).write(isA(LogEntry.class));
}
See more details at HelloServiceBasicTest.java
Important
Keep in mind that the writer are initialized only once during the test run.
Therefore, a more complex example cleans the writer after (or before) each test:
// the static logger instance
@Captor
private ArgumentCaptor<LogEntry> logEntryCaptor;
@MockTinylogWriter
private static Writer writer;
// clean the mock logger after each test
@AfterEach
void tearDown() {
clearInvocations(logger);
}
// use the mock logger in a test
@DisplayName("Names")
@ParameterizedTest(name = "<{0}>")
@ValueSource(strings = {"John", "Jane"})
void names(String name) {
var helloService = new HelloService();
assertDoesNotThrow(() -> helloService.sayHello(name));
verify(writer).write(logEntryCaptor.capture());
assertEquals("Hello " + name + "!", logEntryCaptor.getValue().getMessage());
}
See more details at HelloServiceFullTest.java
To avoid manual cleaning of mock writer you can use the jUnit extension for automation:
@ExtendWith({MockitoExtension.class, MockLoggerExtension.class})
class HelloServiceExtensionTest {
@Captor
private ArgumentCaptor<LogEntry> logEntryCaptor;
@MockTinylogWriter
private static Writer writer;
@DisplayName("Names")
@ParameterizedTest(name = "<{0}>")
@ValueSource(strings = {"John", "Jane"})
void names(String name) {
var helloService = new HelloService();
assertDoesNotThrow(() -> helloService.sayHello(name));
verify(writer).write(logEntryCaptor.capture());
assertEquals("Hello " + name + "!", logEntryCaptor.getValue().getMessage());
}
}
See more details at HelloServiceExtensionTest.java
Also you can use the annotation for automation:
@ExtendWith(MockitoExtension.class)
@MockLoggers
class HelloServiceAnnotationTest {
@Captor
private ArgumentCaptor<LogEntry> logEntryCaptor;
@MockTinylogWriter
private static Writer writer;
@DisplayName("Names")
@ParameterizedTest(name = "<{0}>")
@ValueSource(strings = {"John", "Jane"})
void names(String name) {
when(logger.getMinimumLevel(isNull())).thenReturn(Level.INFO);
var helloService = new HelloService();
assertDoesNotThrow(() -> helloService.sayHello(name));
verify(writer).write(logEntryCaptor.capture());
assertEquals("Hello " + name + "!", logEntryCaptor.getValue().getMessage());
}
}
See more details at HelloServiceAnnotationTest.java
This library can also inject a mock writer instance as a parameter of a test method:
@ExtendWith({MockLoggerExtension.class,MockTinylogWriterExtension.class})
class HelloServiceParameterTest {
@DisplayName("Hello world")
@Test
void helloWorld(Writer writer) {
when(logger.getMinimumLevel(isNull())).thenReturn(Level.INFO);
var helloService = new HelloService();
assertDoesNotThrow(helloService::sayHelloWorld);
verify(writer).write(isA(LogEntry.class));
}
}
See more details ad HelloServiceParameterTest.java
Important
It is necessary to specify the use of this writer in the configuration.
See tinylog.properties.