diff --git a/maven-plugin-testing-harness/pom.xml b/maven-plugin-testing-harness/pom.xml
index fbf9c526..c09b4842 100644
--- a/maven-plugin-testing-harness/pom.xml
+++ b/maven-plugin-testing-harness/pom.xml
@@ -152,6 +152,12 @@ under the License.
mockito-core
4.11.0
+
+ org.mockito
+ mockito-junit-jupiter
+ 4.11.0
+ test
+
org.slf4j
slf4j-simple
diff --git a/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/di/Provides.java b/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/di/Provides.java
new file mode 100644
index 00000000..70fd0dde
--- /dev/null
+++ b/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/di/Provides.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api.di;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Marks a method as a provider of beans for dependency injection.
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Provides {}
diff --git a/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java b/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java
index 3ea09b8f..4bc86a73 100644
--- a/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java
+++ b/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java
@@ -25,6 +25,8 @@
import java.io.StringReader;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -43,7 +45,10 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import com.google.inject.Binder;
+import com.google.inject.Module;
import com.google.inject.internal.ProviderMethodsModule;
+import org.apache.maven.api.di.Provides;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
import org.apache.maven.plugin.Mojo;
@@ -77,6 +82,7 @@
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.platform.commons.support.AnnotationSupport;
+import org.junit.platform.commons.support.HierarchyTraversalMode;
import org.mockito.Mockito;
import org.slf4j.LoggerFactory;
@@ -142,6 +148,7 @@ public void beforeEach(ExtensionContext context) throws Exception {
((DefaultPlexusContainer) getContainer()).addPlexusInjector(Collections.emptyList(), binder -> {
binder.install(ProviderMethodsModule.forObject(context.getRequiredTestInstance()));
+ binder.install(new MavenProvidesModule(context.getRequiredTestInstance()));
binder.requestInjection(context.getRequiredTestInstance());
binder.bind(Log.class).toInstance(new MojoLogWrapper(LoggerFactory.getLogger("anonymous")));
binder.bind(MavenSession.class).toInstance(mockMavenSession());
@@ -190,8 +197,8 @@ private MojoExecution mockMojoExecution() {
*/
private MavenSession mockMavenSession() {
MavenSession session = Mockito.mock(MavenSession.class);
- Mockito.when(session.getUserProperties()).thenReturn(new Properties());
- Mockito.when(session.getSystemProperties()).thenReturn(new Properties());
+ Mockito.lenient().when(session.getUserProperties()).thenReturn(new Properties());
+ Mockito.lenient().when(session.getSystemProperties()).thenReturn(new Properties());
return session;
}
@@ -455,4 +462,32 @@ public File alignToBaseDirectory(File path) {
return evaluator.alignToBaseDirectory(path);
}
}
+
+ private static class MavenProvidesModule implements Module {
+ private final Object testInstance;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void configure(Binder binder) {
+ List providesMethods = AnnotationSupport.findAnnotatedMethods(
+ testInstance.getClass(), Provides.class, HierarchyTraversalMode.BOTTOM_UP);
+
+ for (Method method : providesMethods) {
+ if (method.getParameterCount() > 0) {
+ throw new IllegalArgumentException("Parameterized method are not supported " + method);
+ }
+ try {
+ method.setAccessible(true);
+ Object value = method.invoke(testInstance);
+ binder.bind((Class