8686import org .mockito .Mockito ;
8787import org .slf4j .LoggerFactory ;
8888
89+ import static org .mockito .Mockito .clearInvocations ;
8990import static org .mockito .Mockito .lenient ;
91+ import static org .mockito .Mockito .mockingDetails ;
9092
9193/**
9294 * JUnit's extension to help testing Mojos. The extension should be automatically registered
@@ -151,6 +153,7 @@ public void beforeEach(ExtensionContext context) throws Exception {
151153 binder .install (new MavenProvidesModule (context .getRequiredTestInstance ()));
152154 binder .requestInjection (context .getRequiredTestInstance ());
153155 binder .bind (Log .class ).toInstance (new MojoLogWrapper (LoggerFactory .getLogger ("anonymous" )));
156+ binder .bind (MavenProject .class ).toInstance (mockMavenProject ());
154157 binder .bind (MavenSession .class ).toInstance (mockMavenSession ());
155158 binder .bind (MojoExecution .class ).toInstance (mockMojoExecution ());
156159 });
@@ -180,9 +183,7 @@ public void beforeEach(ExtensionContext context) throws Exception {
180183 * @return a MojoExecution mock
181184 */
182185 private MojoExecution mockMojoExecution () {
183- MojoExecution mockExecution = Mockito .mock (MojoExecution .class );
184- lenient ().when (mockExecution .getMojoDescriptor ()).thenReturn (new MojoDescriptor ());
185- return mockExecution ;
186+ return Mockito .mock (MojoExecution .class );
186187 }
187188
188189 /**
@@ -197,6 +198,17 @@ private MavenSession mockMavenSession() {
197198 return session ;
198199 }
199200
201+ /**
202+ * Default MavenProject mock
203+ *
204+ * @return a MavenProject mock
205+ */
206+ private MavenProject mockMavenProject () {
207+ MavenProject mavenProject = Mockito .mock (MavenProject .class );
208+ lenient ().when (mavenProject .getProperties ()).thenReturn (new Properties ());
209+ return mavenProject ;
210+ }
211+
200212 protected String getPluginDescriptorLocation () {
201213 return "META-INF/maven/plugin.xml" ;
202214 }
@@ -266,27 +278,33 @@ protected Mojo lookupMojo(
266278 PlexusContainer plexusContainer = getContainer (extensionContext );
267279 // pluginkey = groupId : artifactId : version : goal
268280 Mojo mojo = plexusContainer .lookup (Mojo .class , coord [0 ] + ":" + coord [1 ] + ":" + coord [2 ] + ":" + coord [3 ]);
269- for (MojoDescriptor mojoDescriptor : descriptor .getMojos ()) {
270- if (Objects .equals (
271- mojoDescriptor .getImplementation (), mojo .getClass ().getName ())) {
272- if (pluginConfiguration != null ) {
273- pluginConfiguration = finalizeConfig (pluginConfiguration , mojoDescriptor );
274- }
275- }
281+
282+ Optional <MojoDescriptor > mojoDescriptor = descriptor .getMojos ().stream ()
283+ .filter (md ->
284+ Objects .equals (md .getImplementation (), mojo .getClass ().getName ()))
285+ .findFirst ();
286+
287+ if (mojoDescriptor .isPresent ()) {
288+ pluginConfiguration = finalizeConfig (pluginConfiguration , mojoDescriptor .get ());
289+ }
290+
291+ MavenSession session = plexusContainer .lookup (MavenSession .class );
292+ MavenProject mavenProject = plexusContainer .lookup (MavenProject .class );
293+ MojoExecution mojoExecution = plexusContainer .lookup (MojoExecution .class );
294+
295+ if (mockingDetails (session ).isMock ()) {
296+ lenient ().when (session .getCurrentProject ()).thenReturn (mavenProject );
297+ }
298+
299+ if (mockingDetails (mavenProject ).isMock ()) {
300+ lenient ().when (mavenProject .getBasedir ()).thenReturn (new File (getTestBasedir (extensionContext )));
301+ }
302+
303+ if (mojoDescriptor .isPresent () && mockingDetails (mojoExecution ).isMock ()) {
304+ lenient ().when (mojoExecution .getMojoDescriptor ()).thenReturn (mojoDescriptor .get ());
276305 }
306+
277307 if (pluginConfiguration != null ) {
278- MavenSession session = plexusContainer .lookup (MavenSession .class );
279- try {
280- plexusContainer .lookup (MavenProject .class );
281- } catch (ComponentLookupException ignore ) {
282- // nothing
283- }
284- MojoExecution mojoExecution ;
285- try {
286- mojoExecution = plexusContainer .lookup (MojoExecution .class );
287- } catch (ComponentLookupException e ) {
288- mojoExecution = null ;
289- }
290308 ExpressionEvaluator evaluator =
291309 new WrapEvaluator (plexusContainer , new PluginParameterExpressionEvaluator (session , mojoExecution ));
292310 ComponentConfigurator configurator = new BasicComponentConfigurator ();
@@ -299,6 +317,19 @@ protected Mojo lookupMojo(
299317
300318 mojo .setLog (plexusContainer .lookup (Log .class ));
301319
320+ // clear invocations on mocks to avoid test interference
321+ if (mockingDetails (session ).isMock ()) {
322+ clearInvocations (session );
323+ }
324+
325+ if (mockingDetails (mavenProject ).isMock ()) {
326+ clearInvocations (mavenProject );
327+ }
328+
329+ if (mockingDetails (mojoExecution ).isMock ()) {
330+ clearInvocations (mojoExecution );
331+ }
332+
302333 return mojo ;
303334 }
304335
@@ -351,19 +382,6 @@ public static Xpp3Dom extractPluginConfiguration(String artifactId, Xpp3Dom pomD
351382 return pluginConfigurationElement ;
352383 }
353384
354- /**
355- * sometimes the parent element might contain the correct value so generalize that access
356- *
357- * TODO find out where this is probably done elsewhere
358- */
359- private static String resolveFromRootThenParent (Xpp3Dom pluginPomDom , String element ) throws Exception {
360- return Optional .ofNullable (child (pluginPomDom , element ).orElseGet (() -> child (pluginPomDom , "parent" )
361- .flatMap (e -> child (e , element ))
362- .orElse (null )))
363- .map (Xpp3Dom ::getValue )
364- .orElseThrow (() -> new Exception ("unable to determine " + element ));
365- }
366-
367385 /**
368386 * Convenience method to obtain the value of a variable on a mojo that might not have a getter.
369387 * <br>
@@ -425,7 +443,7 @@ public static void setVariableValueToObject(Object object, String variable, Obje
425443 field .set (object , value );
426444 }
427445
428- static class WrapEvaluator implements TypeAwareExpressionEvaluator {
446+ private static class WrapEvaluator implements TypeAwareExpressionEvaluator {
429447
430448 private final PlexusContainer container ;
431449
@@ -473,6 +491,10 @@ public File alignToBaseDirectory(File path) {
473491 private static class MavenProvidesModule implements Module {
474492 private final Object testInstance ;
475493
494+ MavenProvidesModule (Object testInstance ) {
495+ this .testInstance = testInstance ;
496+ }
497+
476498 @ Override
477499 @ SuppressWarnings ("unchecked" )
478500 public void configure (Binder binder ) {
@@ -486,15 +508,14 @@ public void configure(Binder binder) {
486508 try {
487509 method .setAccessible (true );
488510 Object value = method .invoke (testInstance );
511+ if (value == null ) {
512+ throw new IllegalArgumentException ("Provides method returned null: " + method );
513+ }
489514 binder .bind ((Class <Object >) method .getReturnType ()).toInstance (value );
490515 } catch (IllegalAccessException | InvocationTargetException e ) {
491- throw new IllegalStateException (e );
516+ throw new IllegalArgumentException (e );
492517 }
493518 }
494519 }
495-
496- MavenProvidesModule (Object testInstance ) {
497- this .testInstance = testInstance ;
498- }
499520 }
500521}
0 commit comments