Skip to content

Commit

Permalink
Add README and integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalijr2 committed Nov 12, 2024
1 parent d40dc03 commit 236eb29
Show file tree
Hide file tree
Showing 11 changed files with 529 additions and 3 deletions.
4 changes: 1 addition & 3 deletions commons-logging/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ Just put a test dependency to your POM:

The simplest usage example looks like this:
```java
import org.apache.commons.logging.LogFactory;

@Test
void helloWorld() {
var helloService = new HelloService();
Expand Down Expand Up @@ -55,7 +53,7 @@ static void setUpClass() {
// clean the mock logger after each test
@AfterEach
void tearDown() {
clearInvocations(logger);
clearInvocations(log);
}

// use the mock logger in a test
Expand Down
13 changes: 13 additions & 0 deletions slf4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,17 @@
<groupId>io.github.vitalijr2.logging</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<profiles>
<profile>
<build>
<plugins>
<plugin>
<artifactId>maven-invoker-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
</plugin>
</plugins>
</build>
<id>run-its</id>
</profile>
</profiles>
</project>
157 changes: 157 additions & 0 deletions slf4j/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Mock loggers for SLF4J

[SLF4J][slf4j] factory with mock loggers backed by [Mockito][].

> [!WARNING]
> This library does not support _parallel test execution_.
[![Java Version][java-version]][jdk-download]
![Mockito Version][mockito-version]
![Maven Central Last Update][maven-central-last-update]
[![Maven Central][maven-central]][maven-central-link]
[![Javadoc][javadoc]][javadoc-link]

## How to use

Just put a test dependency to your POM:
```xml
<dependency>
<artifactId>mock-loggers-commons-logging</artifactId>
<groupId>io.github.vitalijr2.logging</groupId>
<scope>test</scope>
<version>1.0.0</version>
</dependency>
```

The simplest usage example looks like this:
```java
@Test
void helloWorld() {
var helloService = new HelloService();

assertDoesNotThrow(helloService::sayHelloWorld);

verify(LoggerFactory.getLogger(helloService.getClass())).info("Hello World!");
}
```
See more details at [HelloServiceBasicTest.java](src/it/hello-commons-logging-world/src/test/java/example/hello/HelloServiceBasicTest.java)

> [!IMPORTANT]
> Keep in mind that all loggers are initialized only once during the test run.
Therefore, a more complex example cleans the loggers after (or before) each test:
```java
// the static logger instance
private static Logger logger;

// initialize the mock logger once
@BeforeAll
static void setUpClass() {
logger = LoggerFactory.getLogger(HelloService.class);
}

// 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));

var actualLogger = LoggerFactory.getLogger(helloService.getClass());

verify(actualLogger).info("Hello " + name + "!");
verifyNoMoreInteractions(actualLogger);
}
```
See more details at [HelloServiceFullTest.java](src/it/hello-commons-logging-world/src/test/java/example/hello/HelloServiceFullTest.java)

To avoid manual cleaning of mock loggers you can use the [jUnit extension][junit-extension] for automation.

```java
@ExtendWith(MockLoggerExtension.class)
class HelloServiceExtensionTest {

private static Logger logger;

@BeforeAll
static void setUpClass() {
log = LogFactory.getLog(HelloService.class);
}

@DisplayName("Names")
@ParameterizedTest(name = "<{0}>")
@ValueSource(strings = {"John", "Jane"})
void names(String name) {
var helloService = new HelloService();

assertDoesNotThrow(() -> helloService.sayHello(name));

var actualLogger = LoggerFactory.getLogger(helloService.getClass());

verify(actualLogger).info("Hello " + name + "!");
verifyNoMoreInteractions(actualLogger);
}

}
```
See more details at [HelloServiceExtensionTest.java](src/it/hello-commons-logging-world/src/test/java/example/hello/HelloServiceExtensionTest.java)

Also you can use the annotation for automation.
```java
@MockLoggers
class HelloServiceAnnotationTest {

private static Logger logger;

@BeforeAll
static void setUpClass() {
logger = LogFactory.getLog(HelloService.class);
}

@DisplayName("Names")
@ParameterizedTest(name = "<{0}>")
@ValueSource(strings = {"John", "Jane"})
void names(String name) {
var helloService = new HelloService();

assertDoesNotThrow(() -> helloService.sayHello(name));

var actualLogger = LogFactory.getLog(helloService.getClass());

verify(actualLogger).info("Hello " + name + "!");
verifyNoMoreInteractions(actualLogger);
}

}
```
See more details at [HelloServiceAnnotationTest.java](src/it/hello-commons-logging-world/src/test/java/example/hello/HelloServiceAnnotationTest.java)

[slf4j]: https://www.slf4j.org/

[Mockito]: https://site.mockito.org

[java-version]: https://img.shields.io/static/v1?label=Java&message=11&color=blue&logoColor=E23D28

[jdk-download]: https://www.oracle.com/java/technologies/downloads/#java11

[mockito-version]: https://img.shields.io/static/v1?label=Mockito&message=5.14.2&color=blue&logoColor=E23D28

[maven-central-last-update]: https://img.shields.io/maven-central/last-update/io.github.vitalijr2.logging/mock-loggers-commons-logging

[maven-central]: https://img.shields.io/maven-central/v/io.github.vitalijr2.logging/mock-loggers-commons-logging

[maven-central-link]: https://central.sonatype.com/artifact/io.github.vitalijr2.logging/mock-loggers-commons-logging?smo=true

[javadoc]: https://javadoc.io/badge2/io.github.vitalijr2.logging/mock-loggers-commons-logging/javadoc.svg

[javadoc-link]: https://javadoc.io/doc/io.github.vitalijr2.logging/mock-loggers-commons-logging

[junit-extension]: ../core/
8 changes: 8 additions & 0 deletions slf4j/src/it/hello-slf4j-world/extension-logging.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.level = INFO

handlers = java.util.logging.ConsoleHandler

java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

io.github.vitalijr2.mock.jdk.platform.logging.MockLoggerExtension.level = FINE
99 changes: 99 additions & 0 deletions slf4j/src/it/hello-slf4j-world/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>hello-commons-logging-world</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${java.version}</release>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
<groupId>org.apache.maven.plugins</groupId>
<version>3.13.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<java.util.logging.config.file>extension-logging.properties</java.util.logging.config.file>
</systemPropertyVariables>
</configuration>
<groupId>org.apache.maven.plugins</groupId>
<version>3.5.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<!-- main -->
<dependency>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
<version>2.0.16</version>
</dependency>
<!-- test -->
<!--
<dependency>
<artifactId>@project.artifactId@</artifactId>
<groupId>@project.groupId@</groupId>
<scope>test</scope>
<version>@project.version@</version>
</dependency>
-->
<dependency>
<groupId>io.github.vitalijr2.logging</groupId>
<artifactId>mock-loggers-slf4j</artifactId>
<scope>test</scope>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>hamcrest</artifactId>
<groupId>org.hamcrest</groupId>
<scope>test</scope>
<version>3.0</version>
</dependency>
<dependency>
<artifactId>junit-jupiter-api</artifactId>
<groupId>org.junit.jupiter</groupId>
<scope>test</scope>
<version>${junit-jupiter.version}</version>
</dependency>
<dependency>
<artifactId>junit-jupiter-engine</artifactId>
<groupId>org.junit.jupiter</groupId>
<scope>test</scope>
<version>${junit-jupiter.version}</version>
</dependency>
<dependency>
<artifactId>junit-jupiter-params</artifactId>
<groupId>org.junit.jupiter</groupId>
<scope>test</scope>
<version>${junit-jupiter.version}</version>
</dependency>
<dependency>
<artifactId>mockito-core</artifactId>
<groupId>org.mockito</groupId>
<scope>test</scope>
<version>${mockito.version}</version>
</dependency>
<dependency>
<artifactId>mockito-junit-jupiter</artifactId>
<groupId>org.mockito</groupId>
<scope>test</scope>
<version>${mockito.version}</version>
</dependency>
</dependencies>
<description>Basic example</description>
<groupId>example.hello</groupId>
<modelVersion>4.0.0</modelVersion>
<properties>
<java.version>11</java.version>
<junit-jupiter.version>5.11.3</junit-jupiter.version>
<mockito.version>5.14.2</mockito.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<version>1.0.0</version>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package example.hello;

import static java.util.Objects.requireNonNull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloService {

private final Logger logger = LoggerFactory.getLogger(HelloService.class);

public String sayHelloWorld() {
return sayHello("World");
}

public String sayHello(String name) {
if (requireNonNull(name, "Name is missed").isBlank()) {
throw new IllegalArgumentException("Name is empty");
}

var greeting = "Hello " + name + "!";

if (logger.isInfoEnabled()) {
logger.info(greeting);
}

return greeting;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package example.hello;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import io.github.vitalijr2.logging.mock.MockLoggers;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@MockLoggers
class HelloServiceAnnotationTest {

private static Logger logger;

@BeforeAll
static void setUpClass() {
logger = LoggerFactory.getLogger(HelloService.class);
}

@BeforeEach
void setUp() {
when(logger.isInfoEnabled()).thenReturn(true);
}

@DisplayName("Names")
@ParameterizedTest(name = "<{0}>")
@ValueSource(strings = {"John", "Jane"})
void names(String name) {
var helloService = new HelloService();

assertDoesNotThrow(() -> helloService.sayHello(name));

var actualLogger = LoggerFactory.getLogger(helloService.getClass());

verify(actualLogger).isInfoEnabled();
verify(actualLogger).info("Hello " + name + "!");
verifyNoMoreInteractions(actualLogger);
}

}
Loading

0 comments on commit 236eb29

Please sign in to comment.