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

Support testing injection of complex Mojo parameters #220

Open
kwin opened this issue Oct 21, 2021 · 4 comments
Open

Support testing injection of complex Mojo parameters #220

kwin opened this issue Oct 21, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@kwin
Copy link

kwin commented Oct 21, 2021

As Mojo parameter injection is quite complex (especially when dealing with multiple nested complex objects and collections, look at https://maven.apache.org/guides/plugin/guide-java-plugin-development.html#using-setters or https://maven.apache.org/guides/mini/guide-configuring-plugins.html#Mapping_Lists) it would be useful to test for a successful injection in an IT. Unfortunately the MavenExecutionResult does not give access to the Mojo object nor any of its fields. Would it be possible to serialize it via the Maven extension and deserialize them in the IT?

@kwin kwin added the enhancement New feature or request label Oct 21, 2021
@khmarbaise
Copy link
Owner

First my question would be why would you like to do parameter testing in an integration test? Furthermore the question is what exactly is the problem with the parameters why you need to test that? And finally usually if you really need to test things like that maven-plugin-testing-harness might be a better solution...

It would also be helpful if you could give a real world example what your problem is? Or even better a working example project?

Currently the the integration testing framework is intended for integration testing which mean is starts a separate process to test your test project and does not run in the context of a maven build itself... in consequence of that it has no access to the mojo objects nor it's fields. You can make a simplified picture to start Maven for examplemvn package via separate process (it's like you are calling the testing project manually yourself)...(simplified view!)...

@kwin
Copy link
Author

kwin commented Oct 24, 2021

why would you like to do parameter testing in an integration test?

Because of what I stated in the summary: As Mojo parameter injection is quite complex (especially when dealing with multiple nested complex objects and collections, look at https://maven.apache.org/guides/plugin/guide-java-plugin-development.html#using-setters or https://maven.apache.org/guides/mini/guide-configuring-plugins.html#Mapping_Lists)

what exactly is the problem with the parameters why you need to test that

Sometimes the wrong setters are used for injection

And finally usually if you really need to test things like that maven-plugin-testing-harness might be a better solution...

I thought that this would be a replacement of all other frameworks....

It would also be helpful if you could give a real world example what your problem is? Or even better a working example project?

https://issues.apache.org/jira/browse/JCRVLT-566

in consequence of that it has no access to the mojo objects nor it's fields. You can make a simplified picture to start Maven for examplemvn package via separate process (it's like you are calling the testing project manually yourself)...(simplified view!)...

That is why I proposed to serialize the Mojo object through a Maven extension (then store to a file) and afterwards deserialize from the file in the IT (outside the Maven process)

@khmarbaise
Copy link
Owner

why would you like to do parameter testing in an integration test?

Because of what I stated in the summary: As Mojo parameter injection is quite complex (especially when dealing with multiple nested complex objects and collections, look at https://maven.apache.org/guides/plugin/guide-java-plugin-development.html#using-setters or https://maven.apache.org/guides/mini/guide-configuring-plugins.html#Mapping_Lists)

I know what you have written...

Based on your code example I see some non conventional approaches because you are using <options>..</options> as an entry where usually you use in consequence a setup:

<options>
  <option>...</option>
  <option>...</option>
  <option>...</option>
</options>

Furthermore the part with <maps>...I would not use comma separated parts. I would have used
it like this:

<maps>
  <key>...</key>
  <key>...</key>
</maps>

That's my opinion..

Also from my point of view I would would make example how to configure the plugin based on the complexity of the plugin configuration...to help people how a configuration can look like...

what exactly is the problem with the parameters why you need to test that

Sometimes the wrong setters are used for injection

And finally usually if you really need to test things like that maven-plugin-testing-harness might be a better solution...

I thought that this would be a replacement of all other frameworks....

Is there a reference of that in the project? It focuses on integration testing not on testing within the maven container...

It would also be helpful if you could give a real world example what your problem is? Or even better a working example project?

https://issues.apache.org/jira/browse/JCRVLT-566

in consequence of that it has no access to the mojo objects nor it's fields. You can make a simplified picture to start Maven for examplemvn package via separate process (it's like you are calling the testing project manually yourself)...(simplified view!)...

That is why I proposed to serialize the Mojo object through a Maven extension (then store to a file) and afterwards deserialize from the file in the IT (outside the Maven process)

Yes technically this is possible but I don't like to go that way, but of course you could create an extensions (maven) and create a pull request for this project if needed?

@kornefalk
Copy link

Many plugins relies on proper configuration to be able to work, Some basic parameters can be set as properties to be injected to the tested plugin. However I have not found any way to pass a user class as property parameter.

Example:

<properties>
  <someConfigParameter>someValue</someConfigParameter>
</properties>
<build>
        <plugins>
                 <groupId>com.soebes.itf.jupiter.extension</groupId>
                <artifactId>itf-maven-plugin</artifactId>
...

To set a field in the Mojo class, for unit-testing, you can use reflect, like

import java.lang.reflect.Field;
import lombok.NonNull;

    /**
     * Inject a parameter value to a class (even privat parameters)
     *
     * @param cc The class instance
     * @param fieldName The field name
     * @param value The value
     * @throws NoSuchFieldException If the field does not exist
     * @throws IllegalAccessException If the value is not able to be modified
     */
    public static void setParameter(@NonNull Object cc, @NonNull String fieldName, Object value)
        throws NoSuchFieldException, IllegalAccessException {
        Field field = cc.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(cc, value);
    }

And thereafter you can make a unit test like

@Test
void testMyMojo() throws NoSuchFieldException, IllegalAccessException {
  MyMojo mojo = new MyMojo();
  setParameter(mojo, "myStringParameter", "a value");
  setParameter(mojo, "myIntParameter", 93);
  setParameter(mojo, "myClassParameter", new MyConfigClass(87, asList("one", "two"));
  assertDowsNotThrow(mojo::execute);
}

and basically skip this plugin due to lack of proper test setup for more complex plugins which requires some configuration to be able to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants