Skip to content

Commit

Permalink
Make the core module with keeper and extension. Add an integration te…
Browse files Browse the repository at this point in the history
…st to JDK Platform module.
  • Loading branch information
vitalijr2 committed Nov 12, 2024
1 parent 43fa632 commit 42a9bb5
Show file tree
Hide file tree
Showing 30 changed files with 572 additions and 120 deletions.
9 changes: 6 additions & 3 deletions keeper/pom.xml → core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<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>mock-loggers-keeper</artifactId>
<artifactId>mock-loggers-core</artifactId>
<build>
<plugins>
<plugin>
Expand Down Expand Up @@ -63,9 +63,12 @@
<scope>provided</scope>
</dependency>
</dependencies>
<description>A keeper sends notifications to cleaners when they must clean and reset mock loggers.</description>
<description>The observer pattern is implemented here: cleaners subscribe to notifications from a keeper, who sends
alerts when mock loggers need to be cleaned and reset. Logger factories should implement the cleaner interface and
register themselves with the keeper. The jUnit extension manages the keeper and sends alerts before and after tests.
</description>
<modelVersion>4.0.0</modelVersion>
<name>Logger Keeper</name>
<name>Logger Keeper and jUnit Extension</name>
<parent>
<artifactId>mock-loggers</artifactId>
<groupId>io.github.vitalijr2.logging</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.vitalijr2.logging.keeper;
package io.github.vitalijr2.logging.mock;

import java.util.List;

Expand All @@ -25,6 +25,11 @@
*/
public interface MockLoggerCleaner {

/**
* Receive notification to clean and reset mock loggers.
*
* @return list of logger names that were cleaned and reset
*/
List<String> cleanAndReset();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.vitalijr2.logging.junit;
package io.github.vitalijr2.logging.mock;

import io.github.vitalijr2.logging.keeper.MockLoggerKeeper;
import org.jetbrains.annotations.VisibleForTesting;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.vitalijr2.logging.keeper;
package io.github.vitalijr2.logging.mock;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -54,6 +54,8 @@ public void addCleaner(MockLoggerCleaner cleaner) {

/**
* Send notifications to all cleaners.
*
* @return list of logger names that were cleaned and reset
*/
public List<String> cleanAndReset() {
var loggerNames = new ArrayList<String>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.vitalijr2.logging.junit;
package io.github.vitalijr2.logging.mock;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* The observer pattern is implemented here: cleaners subscribe to notifications from a keeper, who sends alerts when
* mock loggers need to be cleaned and reset. Logger factories should implement the cleaner interface and register
* themselves with the keeper. The jUnit extension manages the keeper and sends alerts before and after tests.
*/
package io.github.vitalijr2.logging.mock;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.vitalijr2.logging.keeper;
package io.github.vitalijr2.logging.mock;

import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.verify;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package io.github.vitalijr2.logging.junit;
package io.github.vitalijr2.logging.mock;

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

import io.github.vitalijr2.logging.keeper.MockLoggerKeeper;
import java.util.List;
import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.vitalijr2.logging.junit;
package io.github.vitalijr2.logging.mock;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.vitalijr2.logging.keeper;
package io.github.vitalijr2.logging.mock;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
Expand Down
15 changes: 14 additions & 1 deletion jdk-platform-logging/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<scope>provided</scope>
</dependency>
<dependency>
<artifactId>mock-loggers-keeper</artifactId>
<artifactId>mock-loggers-core</artifactId>
<groupId>io.github.vitalijr2.logging</groupId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
Expand Down Expand Up @@ -82,4 +82,17 @@
<relativePath>../pom.xml</relativePath>
<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>
152 changes: 152 additions & 0 deletions jdk-platform-logging/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Mock loggers for JDK Platform Logging

[JDK Platform Logging][jdk-logging] Service 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]
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)
![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-jdk-platform-logging</artifactId>
<groupId>io.github.vitalijr2.logging</groupId>
<scope>test</scope>
<version>1.0.0</version>
</dependency>
```

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

assertDoesNotThrow(helloService::sayHelloWorld);

verify(System.getLogger("HelloService")).log(Level.INFO, "Hello World!");
}
```
See more details at [HelloServiceBasicTest.java](src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceBasicTest.java)

It should be taken into account that all loggers are initialized only once during the run of tests.
Therefore, a more complex example cleans the loggers before (or after) each test:
```java
// the static logger instance
private static Logger logger;

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

// 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 logger = System.getLogger("HelloService");

verify(logger).log(Level.INFO, "Hello " + name + "!");
verifyNoMoreInteractions(logger);
}
```
See more details at [HelloServiceFullTest.java](src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceFullTest.java)

You can use the jUnit extension for automation.
```java
@ExtendWith(MockLoggerExtension.class)
class HelloServiceExtensionTest {

private static Logger logger;

@BeforeAll
static void setUpClass() {
logger = System.getLogger("HelloService");
}

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

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

var logger = System.getLogger("HelloService");

verify(logger).log(Level.INFO, "Hello " + name + "!");
verifyNoMoreInteractions(logger);
}

}
```
See more details at [HelloServiceExtensionTest.java](src/it/hello-jdk-platform-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 = System.getLogger("HelloService");
}

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

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

var logger = System.getLogger("HelloService");

verify(logger).log(Level.INFO, "Hello " + name + "!");
verifyNoMoreInteractions(logger);
}

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

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

[jdk-logging]: https://www.baeldung.com/java-9-logging-api "Java Platform Logging API"

[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

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

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

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

[javadoc-link]: https://javadoc.io/doc/io.github.vitalijr2.logging/mock-loggers
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?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-jdk-platform-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.3.1</version>
</plugin>
</plugins>
</build>
<dependencies>
<!-- test -->
<dependency>
<artifactId>@project.artifactId@</artifactId>
<groupId>@project.groupId@</groupId>
<scope>test</scope>
<version>@project.version@</version>
</dependency>
<dependency>
<artifactId>hamcrest</artifactId>
<groupId>org.hamcrest</groupId>
<scope>test</scope>
<version>2.2</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>
Loading

0 comments on commit 42a9bb5

Please sign in to comment.