From eebf43f986f277b801707ddb31e8ad13c6a12dc6 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Fri, 5 Jan 2024 12:16:26 +0100 Subject: [PATCH] junit parameter resolver --- junit5/README.md | 2 +- .../weld/junit5/WeldJunit5Extension.java | 55 ++++++++++++++----- .../JunitParameterResolverAutoWeldTest.java | 8 +++ .../JunitParameterResolverReferenceTest.java | 38 +++++++++++++ .../JunitParameterResolverWeldTest.java | 8 +++ 5 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverAutoWeldTest.java create mode 100644 junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverReferenceTest.java create mode 100644 junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverWeldTest.java diff --git a/junit5/README.md b/junit5/README.md index 930b7bac..5509b9dc 100644 --- a/junit5/README.md +++ b/junit5/README.md @@ -645,7 +645,7 @@ This section describes any additional configuration options this extension offer ### Explicit Parameter Injection As mentioned above, Weld is greedy when it comes to parameter injection. -It will claim the ability to resolve any parameter which is known as a bean type inside the running CDI container. +It will claim the ability to resolve any parameter which is known as a bean type inside the running CDI container except the ones built into JUnit itself. This is mainly for usability, as it would be annoying to constantly type additional annotations to mark which parameter should be injected and which should be left alone. However, we are aware that this might cause trouble if more extensions are competing for parameter resolution. diff --git a/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java b/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java index 430eef2c..6c0b98c7 100644 --- a/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java +++ b/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java @@ -45,7 +45,10 @@ import org.jboss.weld.environment.se.Weld; import org.jboss.weld.inject.WeldInstance; import org.jboss.weld.util.collections.ImmutableList; +import org.junit.jupiter.api.RepetitionInfo; +import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestReporter; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; @@ -54,6 +57,7 @@ import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.io.TempDir; /** * JUnit 5 extension allowing to bootstrap Weld SE container for each @Test method (or once per test class @@ -108,16 +112,6 @@ private static void storeExplicitParamResolutionInformation(ExtensionContext ec) } - @Override - public void afterAll(ExtensionContext context) { - if (determineTestLifecycle(context).equals(PER_CLASS)) { - WeldInitiator initiator = getInitiatorFromStore(context); - if (initiator != null) { - initiator.shutdownWeld(); - } - } - } - @Override public void beforeAll(ExtensionContext context) { // we are storing them into root context, hence only needs to be done once per test suite @@ -130,6 +124,11 @@ public void beforeAll(ExtensionContext context) { startWeldContainerIfAppropriate(PER_CLASS, context); } + @Override + public void beforeEach(ExtensionContext extensionContext) { + startWeldContainerIfAppropriate(PER_METHOD, extensionContext); + } + @Override public void afterEach(ExtensionContext context) { if (determineTestLifecycle(context).equals(PER_METHOD)) { @@ -140,6 +139,16 @@ public void afterEach(ExtensionContext context) { } } + @Override + public void afterAll(ExtensionContext context) { + if (determineTestLifecycle(context).equals(PER_CLASS)) { + WeldInitiator initiator = getInitiatorFromStore(context); + if (initiator != null) { + initiator.shutdownWeld(); + } + } + } + protected void weldInit(ExtensionContext context, Weld weld, WeldInitiator.Builder weldInitiatorBuilder) { weld.addPackage(false, context.getRequiredTestClass()); } @@ -162,6 +171,10 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + // do not attempt to resolve JUnit 5 built-in parameters + if (isJUnitResolvedParameter(parameterContext)) { + return false; + } // if weld container isn't up yet or if it's not Method, we don't resolve it if (getContainerFromStore(extensionContext) == null || (!(parameterContext.getDeclaringExecutable() instanceof Method))) { @@ -191,6 +204,23 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon } } + /** + * @see {@code org.junit.jupiter.engine.extension.TestInfoParameterResolver.supportsParameter} + * @see {@code org.junit.jupiter.engine.extension.RepetitionExtension.supportsParameter} + * @see {@code org.junit.jupiter.engine.extension.TestReporterParameterResolver.supportsParameter} + * @see {@code org.junit.jupiter.engine.extension.TempDirectory.supportsParameter} + */ + private boolean isJUnitResolvedParameter(ParameterContext parameterContext) { + Class type = parameterContext.getParameter().getType(); + if (type == TestInfo.class || type == RepetitionInfo.class || type == TestReporter.class) { + return true; + } + if (parameterContext.isAnnotated(TempDir.class)) { + return true; + } + return false; + } + private List resolveQualifiers(ParameterContext pc, BeanManager bm) { List qualifiers = new ArrayList<>(); if (pc.getParameter().getAnnotations().length == 0) { @@ -225,11 +255,6 @@ private TestInstance.Lifecycle determineTestLifecycle(ExtensionContext ec) { } } - @Override - public void beforeEach(ExtensionContext extensionContext) { - startWeldContainerIfAppropriate(PER_METHOD, extensionContext); - } - private void startWeldContainerIfAppropriate(TestInstance.Lifecycle expectedLifecycle, ExtensionContext context) { // if the lifecycle is what we expect it to be, start Weld container if (determineTestLifecycle(context).equals(expectedLifecycle)) { diff --git a/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverAutoWeldTest.java b/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverAutoWeldTest.java new file mode 100644 index 00000000..e1440a9a --- /dev/null +++ b/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverAutoWeldTest.java @@ -0,0 +1,8 @@ +package org.jboss.weld.junit5.compat; + +import org.jboss.weld.junit5.auto.EnableAutoWeld; + +@EnableAutoWeld +class JunitParameterResolverAutoWeldTest extends JunitParameterResolverReferenceTest { + +} diff --git a/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverReferenceTest.java b/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverReferenceTest.java new file mode 100644 index 00000000..aac9265d --- /dev/null +++ b/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverReferenceTest.java @@ -0,0 +1,38 @@ +package org.jboss.weld.junit5.compat; + +import java.nio.file.Path; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.RepetitionInfo; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.TestReporter; +import org.junit.jupiter.api.io.TempDir; + +/** + * This test runs without CDI in order to demonstrate that it works with plain JUnit. + */ +class JunitParameterResolverReferenceTest { + + @Test + void testResolveTestInfo(TestInfo testInfo) { + Assertions.assertNotNull(testInfo); + } + + @RepeatedTest(1) + void testResolveRepetitionInfo(RepetitionInfo repetitionInfo) { + Assertions.assertNotNull(repetitionInfo); + } + + @Test + void testResolveTestReporter(TestReporter testReporter) { + Assertions.assertNotNull(testReporter); + } + + @Test + void testResolveTempDir(@TempDir Path tempDir) { + Assertions.assertNotNull(tempDir); + } + +} diff --git a/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverWeldTest.java b/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverWeldTest.java new file mode 100644 index 00000000..d6b34640 --- /dev/null +++ b/junit5/src/test/java/org/jboss/weld/junit5/compat/JunitParameterResolverWeldTest.java @@ -0,0 +1,8 @@ +package org.jboss.weld.junit5.compat; + +import org.jboss.weld.junit5.EnableWeld; + +@EnableWeld +class JunitParameterResolverWeldTest extends JunitParameterResolverReferenceTest { + +}