diff --git a/keeper/pom.xml b/core/pom.xml similarity index 83% rename from keeper/pom.xml rename to core/pom.xml index c952df5..b0bd8b3 100644 --- a/keeper/pom.xml +++ b/core/pom.xml @@ -17,7 +17,7 @@ - mock-loggers-keeper + mock-loggers-core @@ -63,9 +63,12 @@ provided - A keeper sends notifications to cleaners when they must clean and reset mock loggers. + 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. + 4.0.0 - Logger Keeper + Logger Keeper and jUnit Extension mock-loggers io.github.vitalijr2.logging diff --git a/keeper/src/main/java/io/github/vitalijr2/logging/keeper/MockLoggerCleaner.java b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerCleaner.java similarity index 84% rename from keeper/src/main/java/io/github/vitalijr2/logging/keeper/MockLoggerCleaner.java rename to core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerCleaner.java index c6bbb46..d8c45f8 100644 --- a/keeper/src/main/java/io/github/vitalijr2/logging/keeper/MockLoggerCleaner.java +++ b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerCleaner.java @@ -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; @@ -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 cleanAndReset(); /** diff --git a/junit-extension/src/main/java/io/github/vitalijr2/logging/junit/MockLoggerExtension.java b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerExtension.java similarity index 97% rename from junit-extension/src/main/java/io/github/vitalijr2/logging/junit/MockLoggerExtension.java rename to core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerExtension.java index 249aea5..e9a29b9 100644 --- a/junit-extension/src/main/java/io/github/vitalijr2/logging/junit/MockLoggerExtension.java +++ b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerExtension.java @@ -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; diff --git a/keeper/src/main/java/io/github/vitalijr2/logging/keeper/MockLoggerKeeper.java b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerKeeper.java similarity index 94% rename from keeper/src/main/java/io/github/vitalijr2/logging/keeper/MockLoggerKeeper.java rename to core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerKeeper.java index 27fd4bf..82d7bcb 100644 --- a/keeper/src/main/java/io/github/vitalijr2/logging/keeper/MockLoggerKeeper.java +++ b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggerKeeper.java @@ -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; @@ -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 cleanAndReset() { var loggerNames = new ArrayList(); diff --git a/junit-extension/src/main/java/io/github/vitalijr2/logging/junit/MockLoggers.java b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggers.java similarity index 96% rename from junit-extension/src/main/java/io/github/vitalijr2/logging/junit/MockLoggers.java rename to core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggers.java index f7170e6..5678f7e 100644 --- a/junit-extension/src/main/java/io/github/vitalijr2/logging/junit/MockLoggers.java +++ b/core/src/main/java/io/github/vitalijr2/logging/mock/MockLoggers.java @@ -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; diff --git a/core/src/main/java/io/github/vitalijr2/logging/mock/package-info.java b/core/src/main/java/io/github/vitalijr2/logging/mock/package-info.java new file mode 100644 index 0000000..1268e57 --- /dev/null +++ b/core/src/main/java/io/github/vitalijr2/logging/mock/package-info.java @@ -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; \ No newline at end of file diff --git a/keeper/src/test/java/io/github/vitalijr2/logging/keeper/MockLoggerCleanerTest.java b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerCleanerTest.java similarity index 94% rename from keeper/src/test/java/io/github/vitalijr2/logging/keeper/MockLoggerCleanerTest.java rename to core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerCleanerTest.java index 21c92a2..448885f 100644 --- a/keeper/src/test/java/io/github/vitalijr2/logging/keeper/MockLoggerCleanerTest.java +++ b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerCleanerTest.java @@ -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; diff --git a/junit-extension/src/test/java/io/github/vitalijr2/logging/junit/MockLoggerExtensionFastTest.java b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerExtensionFastTest.java similarity index 95% rename from junit-extension/src/test/java/io/github/vitalijr2/logging/junit/MockLoggerExtensionFastTest.java rename to core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerExtensionFastTest.java index 5048570..dca6ed5 100644 --- a/junit-extension/src/test/java/io/github/vitalijr2/logging/junit/MockLoggerExtensionFastTest.java +++ b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerExtensionFastTest.java @@ -1,4 +1,4 @@ -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; @@ -6,7 +6,6 @@ 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; diff --git a/junit-extension/src/test/java/io/github/vitalijr2/logging/junit/MockLoggerExtensionSlowTest.java b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerExtensionSlowTest.java similarity index 92% rename from junit-extension/src/test/java/io/github/vitalijr2/logging/junit/MockLoggerExtensionSlowTest.java rename to core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerExtensionSlowTest.java index 0cf23b9..4cb43bc 100644 --- a/junit-extension/src/test/java/io/github/vitalijr2/logging/junit/MockLoggerExtensionSlowTest.java +++ b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerExtensionSlowTest.java @@ -1,4 +1,4 @@ -package io.github.vitalijr2.logging.junit; +package io.github.vitalijr2.logging.mock; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; diff --git a/keeper/src/test/java/io/github/vitalijr2/logging/keeper/MockLoggerKeeperTest.java b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerKeeperTest.java similarity index 97% rename from keeper/src/test/java/io/github/vitalijr2/logging/keeper/MockLoggerKeeperTest.java rename to core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerKeeperTest.java index 73c37fa..551afda 100644 --- a/keeper/src/test/java/io/github/vitalijr2/logging/keeper/MockLoggerKeeperTest.java +++ b/core/src/test/java/io/github/vitalijr2/logging/mock/MockLoggerKeeperTest.java @@ -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; diff --git a/jdk-platform-logging/pom.xml b/jdk-platform-logging/pom.xml index 0f62c39..90b7b9f 100644 --- a/jdk-platform-logging/pom.xml +++ b/jdk-platform-logging/pom.xml @@ -42,7 +42,7 @@ provided - mock-loggers-keeper + mock-loggers-core io.github.vitalijr2.logging 1.0.0-SNAPSHOT @@ -82,4 +82,17 @@ ../pom.xml 1.0.0-SNAPSHOT + + + + + + maven-invoker-plugin + org.apache.maven.plugins + + + + run-its + + \ No newline at end of file diff --git a/jdk-platform-logging/readme.md b/jdk-platform-logging/readme.md new file mode 100644 index 0000000..f359114 --- /dev/null +++ b/jdk-platform-logging/readme.md @@ -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 + + mock-loggers-jdk-platform-logging + io.github.vitalijr2.logging + test + 1.0.0 + +``` + +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 diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/extension-logging.properties b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/extension-logging.properties new file mode 100644 index 0000000..cd35a2c --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/extension-logging.properties @@ -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 diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/pom.xml b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/pom.xml new file mode 100644 index 0000000..3108fbf --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/pom.xml @@ -0,0 +1,85 @@ + + + hello-jdk-platform-logging-world + + + + maven-compiler-plugin + + ${java.version} + ${java.version} + ${java.version} + + org.apache.maven.plugins + 3.13.0 + + + maven-surefire-plugin + + + extension-logging.properties + + + org.apache.maven.plugins + 3.3.1 + + + + + + + @project.artifactId@ + @project.groupId@ + test + @project.version@ + + + hamcrest + org.hamcrest + test + 2.2 + + + junit-jupiter-api + org.junit.jupiter + test + ${junit-jupiter.version} + + + junit-jupiter-engine + org.junit.jupiter + test + ${junit-jupiter.version} + + + junit-jupiter-params + org.junit.jupiter + test + ${junit-jupiter.version} + + + mockito-core + org.mockito + test + ${mockito.version} + + + mockito-junit-jupiter + org.mockito + test + ${mockito.version} + + + Basic example + example.hello + 4.0.0 + + 11 + 5.11.3 + 5.14.2 + UTF-8 + + 1.0.0 + diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/main/java/example/hello/HelloService.java b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/main/java/example/hello/HelloService.java new file mode 100644 index 0000000..6693d81 --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/main/java/example/hello/HelloService.java @@ -0,0 +1,30 @@ +package example.hello; + +import static java.util.Objects.requireNonNull; + +import java.lang.System.Logger; +import java.lang.System.Logger.Level; + +public class HelloService { + + private final Logger logger = System.getLogger("HelloService"); + + 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.isLoggable(Level.INFO)) { + logger.log(Level.INFO, greeting); + } + + return greeting; + } + +} diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceAnnotationTest.java b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceAnnotationTest.java new file mode 100644 index 0000000..0dee262 --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceAnnotationTest.java @@ -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 java.lang.System.Logger; +import java.lang.System.Logger.Level; +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; + +@MockLoggers +class HelloServiceAnnotationTest { + + private static Logger logger; + + @BeforeAll + static void setUpClass() { + logger = System.getLogger("HelloService"); + } + + @BeforeEach + void setUp() { + when(logger.isLoggable(Level.INFO)).thenReturn(true); + } + + @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).isLoggable(Level.INFO); + verify(logger).log(Level.INFO, "Hello " + name + "!"); + verifyNoMoreInteractions(logger); + } + +} diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceBasicTest.java b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceBasicTest.java new file mode 100644 index 0000000..e896fef --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceBasicTest.java @@ -0,0 +1,23 @@ +package example.hello; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.verify; + +import java.lang.System.Logger.Level; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class HelloServiceBasicTest { + + @DisplayName("Hello world") + @Test + void helloWorld() { + var helloService = new HelloService(); + + assertDoesNotThrow(helloService::sayHelloWorld); + + verify(System.getLogger("HelloService")).isLoggable(isA(Level.class)); + } + +} diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceExtensionTest.java b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceExtensionTest.java new file mode 100644 index 0000000..f2b5450 --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceExtensionTest.java @@ -0,0 +1,48 @@ +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.MockLoggerExtension; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@ExtendWith(MockLoggerExtension.class) +class HelloServiceExtensionTest { + + private static Logger logger; + + @BeforeAll + static void setUpClass() { + logger = System.getLogger("HelloService"); + } + + @BeforeEach + void setUp() { + when(logger.isLoggable(Level.INFO)).thenReturn(true); + } + + @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).isLoggable(Level.INFO); + verify(logger).log(Level.INFO, "Hello " + name + "!"); + verifyNoMoreInteractions(logger); + } + +} diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceFullTest.java b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceFullTest.java new file mode 100644 index 0000000..5a91712 --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/src/test/java/example/hello/HelloServiceFullTest.java @@ -0,0 +1,70 @@ +package example.hello; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.StringStartsWith.startsWith; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +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.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +class HelloServiceFullTest { + + private static Logger logger; + + @BeforeAll + static void setUpClass() { + logger = System.getLogger("HelloService"); + } + + @BeforeEach + void setUp() throws Exception { + clearInvocations(logger); + reset(logger); + } + + @DisplayName("Names") + @ParameterizedTest(name = "<{0}>") + @ValueSource(strings = {"John", "Jane"}) + void names(String name) { + var helloService = new HelloService(); + + when(logger.isLoggable(Level.INFO)).thenReturn(true); + + assertDoesNotThrow(() -> helloService.sayHello(name)); + + var logger = System.getLogger("HelloService"); + + verify(logger).isLoggable(Level.INFO); + verify(logger).log(Level.INFO, "Hello " + name + "!"); + verifyNoMoreInteractions(logger); + } + + @DisplayName("Null or empty name") + @ParameterizedTest(name = "<{0}>") + @NullAndEmptySource + @ValueSource(strings = " ") + void nullOrEmptyName(String name) { + var helloService = new HelloService(); + + var exception = assertThrows(RuntimeException.class, () -> helloService.sayHello(name)); + + verifyNoInteractions(System.getLogger("HelloService")); + + assertThat(exception.getMessage(), startsWith("Name is")); + } + + +} diff --git a/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/verify.groovy b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/verify.groovy new file mode 100644 index 0000000..73fad44 --- /dev/null +++ b/jdk-platform-logging/src/it/hello-jdk-platform-logging-world/verify.groovy @@ -0,0 +1 @@ +println "Hello World!" diff --git a/jdk-platform-logging/src/it/settings.xml b/jdk-platform-logging/src/it/settings.xml new file mode 100644 index 0000000..12780df --- /dev/null +++ b/jdk-platform-logging/src/it/settings.xml @@ -0,0 +1,35 @@ + + + + + + true + + it-repo + + + local.central + + true + + + true + + @localRepositoryUrl@ + + + + + local.central + + true + + + true + + @localRepositoryUrl@ + + + + + diff --git a/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/platform/MockLoggerFinder.java b/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinder.java similarity index 95% rename from jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/platform/MockLoggerFinder.java rename to jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinder.java index 4910e83..708246e 100644 --- a/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/platform/MockLoggerFinder.java +++ b/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinder.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.vitalijr2.logging.platform; +package io.github.vitalijr2.logging.mock.platform; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; -import io.github.vitalijr2.logging.keeper.MockLoggerCleaner; +import io.github.vitalijr2.logging.mock.MockLoggerCleaner; import java.lang.System.Logger; import java.lang.System.LoggerFinder; import java.util.ArrayList; diff --git a/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/platform/package-info.java b/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/mock/platform/package-info.java similarity index 71% rename from jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/platform/package-info.java rename to jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/mock/platform/package-info.java index 21fedd7..6a8debd 100644 --- a/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/platform/package-info.java +++ b/jdk-platform-logging/src/main/java/io/github/vitalijr2/logging/mock/platform/package-info.java @@ -3,4 +3,4 @@ * * @since 1.0.0 */ -package io.github.vitalijr2.logging.platform; +package io.github.vitalijr2.logging.mock.platform; diff --git a/jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder b/jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder index b948b25..2098a34 100644 --- a/jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder +++ b/jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder @@ -1 +1 @@ -io.github.vitalijr2.logging.platform.MockLoggerFinder +io.github.vitalijr2.logging.mock.platform.MockLoggerFinder diff --git a/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/platform/MockLoggerFinderFastTest.java b/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinderFastTest.java similarity index 97% rename from jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/platform/MockLoggerFinderFastTest.java rename to jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinderFastTest.java index 8d0c483..d34d1cf 100644 --- a/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/platform/MockLoggerFinderFastTest.java +++ b/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinderFastTest.java @@ -1,4 +1,4 @@ -package io.github.vitalijr2.logging.platform; +package io.github.vitalijr2.logging.mock.platform; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsIterableContainingInOrder.contains; diff --git a/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/platform/MockLoggerFinderSlowTest.java b/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinderSlowTest.java similarity index 92% rename from jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/platform/MockLoggerFinderSlowTest.java rename to jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinderSlowTest.java index d08ab71..d10e02e 100644 --- a/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/platform/MockLoggerFinderSlowTest.java +++ b/jdk-platform-logging/src/test/java/io/github/vitalijr2/logging/mock/platform/MockLoggerFinderSlowTest.java @@ -1,10 +1,10 @@ -package io.github.vitalijr2.logging.platform; +package io.github.vitalijr2.logging.mock.platform; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import io.github.vitalijr2.logging.keeper.MockLoggerKeeper; +import io.github.vitalijr2.logging.mock.MockLoggerKeeper; import java.lang.System.Logger; import java.lang.System.Logger.Level; import org.junit.jupiter.api.AfterEach; diff --git a/junit-extension/pom.xml b/junit-extension/pom.xml deleted file mode 100644 index 8bc3fa5..0000000 --- a/junit-extension/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - mock-loggers-junit-extension - - - - maven-surefire-plugin - org.apache.maven.plugins - - - maven-failsafe-plugin - org.apache.maven.plugins - - - jacoco-maven-plugin - org.jacoco - - - - - - - annotations - org.jetbrains - provided - - - junit-jupiter-api - org.junit.jupiter - provided - - - junit-platform-commons - org.junit.platform - provided - - - mock-loggers-keeper - io.github.vitalijr2.logging - 1.0.0-SNAPSHOT - - - - junit-jupiter-engine - org.junit.jupiter - provided - - - junit-jupiter-params - org.junit.jupiter - provided - - - mockito-junit-jupiter - org.mockito - provided - - - 4.0.0 - jUnit Extension - - mock-loggers - io.github.vitalijr2.logging - 1.0.0-SNAPSHOT - - \ No newline at end of file diff --git a/keeper/src/main/java/io/github/vitalijr2/logging/keeper/package-info.java b/keeper/src/main/java/io/github/vitalijr2/logging/keeper/package-info.java deleted file mode 100644 index a392dff..0000000 --- a/keeper/src/main/java/io/github/vitalijr2/logging/keeper/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * This implements the observer pattern: cleaners subscribe to notifications from a keeper, who sends alerts when they - * need to clean and reset mock loggers. Logger factories should implement the cleaner interface and register themselves - * with the keeper. - */ -package io.github.vitalijr2.logging.keeper; \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0a118e5..d51d9f2 100644 --- a/pom.xml +++ b/pom.xml @@ -192,6 +192,11 @@ org.apache.maven.plugins 3.5.2 + + org.apache.maven.plugins + maven-install-plugin + 3.1.3 + maven-invoker-plugin @@ -388,9 +393,8 @@ 4.0.0 + core jdk-platform-logging - junit-extension - keeper Mock Loggers pom @@ -448,23 +452,34 @@ + clean install - maven-failsafe-plugin + jacoco-maven-plugin + org.jacoco true - org.apache.maven.plugins - maven-surefire-plugin + maven-failsafe-plugin true org.apache.maven.plugins - maven-invoker-plugin + maven-install-plugin + org.apache.maven.plugins + + false + + + + maven-surefire-plugin + + true + org.apache.maven.plugins diff --git a/readme.md b/readme.md index 5a7dbaa..90fe501 100644 --- a/readme.md +++ b/readme.md @@ -41,7 +41,7 @@ void helloWorld() { verify(System.getLogger("HelloService")).log(Level.INFO, "Hello World!"); } ``` -See more details at [HelloServiceBasicTest.java](src/it/hello-world/src/test/java/example/hello/HelloServiceBasicTest.java) +See more details at [HelloServiceBasicTest.java](jdk-platform-logging/src/it/hello-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: @@ -76,7 +76,7 @@ void names(String name) { verifyNoMoreInteractions(logger); } ``` -See more details at [HelloServiceFullTest.java](src/it/hello-world/src/test/java/example/hello/HelloServiceFullTest.java) +See more details at [HelloServiceFullTest.java](jdk-platform-logging/src/it/hello-world/src/test/java/example/hello/HelloServiceFullTest.java) Since the version **1.1.0** you can use the jUnit extension for automation. ```java @@ -106,7 +106,7 @@ class HelloServiceExtensionTest { } ``` -See more details at [HelloServiceExtensionTest.java](src/it/hello-world/src/test/java/example/hello/HelloServiceExtensionTest.java) +See more details at [HelloServiceExtensionTest.java](jdk-platform-logging/src/it/hello-world/src/test/java/example/hello/HelloServiceExtensionTest.java) Since the version **1.1.3** you can use the annotation for automation. ```java @@ -136,7 +136,7 @@ class HelloServiceAnnotationTest { } ``` -See more details at [HelloServiceAnnotationTest.java](src/it/hello-world/src/test/java/example/hello/HelloServiceAnnotationTest.java) +See more details at [HelloServiceAnnotationTest.java](jdk-platform-logging/src/it/hello-world/src/test/java/example/hello/HelloServiceAnnotationTest.java) ## Credits