Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MNG-8525] Add an integration test with Maven 4 Plugin Sample #2055

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

sparsick
Copy link

Add an integration test for a Maven 4 plugin sample.

Based on the sample for Maven 3 plugins

Thanks, @gnodet, for resolving some issues.

Following this checklist to help us incorporate your
contribution quickly and easily:

  • Make sure there is a JIRA issue filed
    for the change (usually before you start working on it). Trivial changes like typos do not
    require a JIRA issue. Your pull request should address just this issue, without
    pulling in other changes.
  • Each commit in the pull request should have a meaningful subject line and body.
  • Format the pull request title like [MNG-XXX] SUMMARY,
    where you replace MNG-XXX and SUMMARY with the appropriate JIRA issue.
  • Also format the first line of the commit message like [MNG-XXX] SUMMARY.
    Best practice is to use the JIRA issue title in both the pull request title and in the first line of the commit message.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Run mvn clean verify to make sure basic checks pass. A more thorough check will
    be performed on your pull request automatically.
  • You have run the Core IT successfully.

If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.

To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.

based on sample for JSR 330 plugins
Copy link
Contributor

@gnodet gnodet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add unit test and an IT for the plugin.
This way, this would be a good example to point at when starting a new plugin.

A mojo unit test can be written similar to
https://github.com/apache/maven-deploy-plugin/blob/master/src/test/java/org/apache/maven/plugins/deploy/DeployMojoTest.java

I think it would be nice to add a mojo parameter to HelloMojo, maybe pass it to the hello() method. And maybe a skip parameter, that's an easy one to test.

For the IT, we should use the same logic as the outer MavenITmng8525MavenDIPlugin but inside a plugin IT. See https://github.com/apache/maven-deploy-plugin/tree/master/src/it.

We can do it in another PR if you prefer.

@sparsick
Copy link
Author

Thanks, @gnodet, for your feedback. I will expand the pull request.

@sparsick sparsick marked this pull request as draft January 23, 2025 11:26
@sparsick
Copy link
Author

I'd like to share a few thoughts that I have during writing the tests (if the mailing list is a better place, I can also share them there):

  • During testing I miss a possibility where I can inject mocks to the mojo.
  • Is it possible to introduce constructor injection? It would be easier to write mojo test with plain JUnit5. I know that I can add a constructor with parameters, but then I also have to a default constructor because of the DI framework. It feels noisy.

This construction

   @Inject
    public HelloMojo(MavenDIComponent component) {
        this.component = component;
    }

results in runtime error:

org.junit.jupiter.api.extension.ParameterResolutionException: Unable to resolve mojo
        at org.apache.maven.api.plugin.testing.MojoExtension.resolveParameter(MojoExtension.java:201)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.apache.maven.di.impl.DIException: Error while initializing binding BindingToConstructor[@Named("org.apache.maven.plugins:mavendi-maven-plugin:0.0.1-SNAPSHOT:hello") HelloMojoFactory][]
        at org.apache.maven.di.impl.Binding$1.lambda$compile$0(Binding.java:109)
        at org.apache.maven.di.impl.InjectorImpl.getInstance(InjectorImpl.java:75)
        at org.apache.maven.api.di.testing.MavenDIExtension.lookup(MavenDIExtension.java:99)
        at org.apache.maven.api.plugin.testing.MojoExtension.resolveParameter(MojoExtension.java:181)
        ... 2 more
Caused by: org.apache.maven.di.impl.DIException: Failed to call constructor public org.apache.maven.plugins.HelloMojoFactory() to provide requested key @Named("org.apache.maven.plugins:mavendi-maven-plugin:0.0.1-SNAPSHOT:hello") HelloMojoFactory
        at org.apache.maven.di.impl.ReflectionUtils.lambda$bindingFromConstructor$7(ReflectionUtils.java:373)
        at org.apache.maven.di.impl.Binding$BindingToConstructor.lambda$compile$0(Binding.java:188)
        at org.apache.maven.di.impl.Binding$1.lambda$compile$0(Binding.java:105)
        ... 5 more
Caused by: java.lang.NoSuchMethodError: org.apache.maven.plugins.HelloMojo: method 'void <init>()' not found
        at org.apache.maven.plugins.HelloMojoFactory.<init>(HelloMojoFactory.java)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at org.apache.maven.di.impl.ReflectionUtils.lambda$bindingFromConstructor$7(ReflectionUtils.java:360)
        ... 7 more

@sparsick sparsick requested a review from gnodet January 23, 2025 16:12
@sparsick sparsick marked this pull request as ready for review January 23, 2025 16:13
@gnodet
Copy link
Contributor

gnodet commented Jan 23, 2025

I'd like to share a few thoughts that I have during writing the tests (if the mailing list is a better place, I can also share them there):

  • During testing I miss a possibility where I can inject mocks to the mojo.
  • Is it possible to introduce constructor injection? It would be easier to write mojo test with plain JUnit5. I know that I can add a constructor with parameters, but then I also have to a default constructor because of the DI framework. It feels noisy.

This construction

   @Inject
    public HelloMojo(MavenDIComponent component) {
        this.component = component;
    }

results in runtime error:

org.junit.jupiter.api.extension.ParameterResolutionException: Unable to resolve mojo
        at org.apache.maven.api.plugin.testing.MojoExtension.resolveParameter(MojoExtension.java:201)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.apache.maven.di.impl.DIException: Error while initializing binding BindingToConstructor[@Named("org.apache.maven.plugins:mavendi-maven-plugin:0.0.1-SNAPSHOT:hello") HelloMojoFactory][]
        at org.apache.maven.di.impl.Binding$1.lambda$compile$0(Binding.java:109)
        at org.apache.maven.di.impl.InjectorImpl.getInstance(InjectorImpl.java:75)
        at org.apache.maven.api.di.testing.MavenDIExtension.lookup(MavenDIExtension.java:99)
        at org.apache.maven.api.plugin.testing.MojoExtension.resolveParameter(MojoExtension.java:181)
        ... 2 more
Caused by: org.apache.maven.di.impl.DIException: Failed to call constructor public org.apache.maven.plugins.HelloMojoFactory() to provide requested key @Named("org.apache.maven.plugins:mavendi-maven-plugin:0.0.1-SNAPSHOT:hello") HelloMojoFactory
        at org.apache.maven.di.impl.ReflectionUtils.lambda$bindingFromConstructor$7(ReflectionUtils.java:373)
        at org.apache.maven.di.impl.Binding$BindingToConstructor.lambda$compile$0(Binding.java:188)
        at org.apache.maven.di.impl.Binding$1.lambda$compile$0(Binding.java:105)
        ... 5 more
Caused by: java.lang.NoSuchMethodError: org.apache.maven.plugins.HelloMojo: method 'void <init>()' not found
        at org.apache.maven.plugins.HelloMojoFactory.<init>(HelloMojoFactory.java)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at org.apache.maven.di.impl.ReflectionUtils.lambda$bindingFromConstructor$7(ReflectionUtils.java:360)
        ... 7 more

It is possible to inject a mock component into the mojo in unit test.
See how it can be done at:
https://github.com/apache/maven-install-plugin/blob/master/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java#L162-L172
That one will be injected in the mojo under test:
https://github.com/apache/maven-install-plugin/blob/master/src/main/java/org/apache/maven/plugins/install/InstallMojo.java#L55

@sparsick
Copy link
Author

Thanks for the link. I will adjust the test to demonstrate it.

@sparsick sparsick requested a review from gnodet January 24, 2025 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants