title: hard time mojo testing with maven-plugin-testing-harness
body: <p>My plugin mojo test class leverages <a href="https://maven.apache.org/plugin-testing/maven-plugin-testing-harness/" rel="nofollow noreferrer"><code>maven-plugin-test-harness</code></a> to build the complete maven environment with all pom config, plexus container context and repo access. </p>
  
  <p>The following should all actually work:</p>
  
  <ol>
  <li>the test will refer to a test <code>pom.xml</code> in the plugin project's test resources directory</li>
  <li>the mojo will be populated with defaults from the mojo annotations</li>
  <li>all specified configuration in the test pom is accepted</li>
  <li>the maven project object is initialised </li>
  <li>all dependencies from the repo are available</li>
  <li>the tests should pass in IntelliJ IDE as well as Maven on CI server</li>
  </ol>
  
  <p>Because of the lack of concrete working examples I've been trying many different fixes using what I've collected from SO, and other blogs or articles online.</p>
  
  <p>I am currently struggling to get the maven to resolve the artifacts. While I've got the dependency list from the maven project object, the artifact list is empty.</p>
  
  <p>This is what I've built up by dissecting <code>AbstractMojoTestCase</code>. </p>
  
  <p>I can't use <code>MojoRule</code> because JUnit5 doesn't use <code>@Rules</code> anymore. </p>
  
  <p>Plus, some of the maven API calls are deprecated, but I couldn't find a new implementation. I think it won't come until mvn4. See the quote below.</p>
  
  <pre><code>@BeforeEach
  protected void setUp() throws Exception {
      super.setUp();
      cleanUp();
      ClassLoader classLoader = getClass().getClassLoader();
      URL url = classLoader.getResource(TEST_POM);
      if (url == null) {
          throw new MojoExecutionException(String.format(
                  "Cannot locate %s", TEST_POM));
      }
      File pom = new File(url.getFile());
      //noinspection deprecation - wait on maven-plugin-testing-harness update
      MavenSettingsBuilder mavenSettingsBuilder = (MavenSettingsBuilder)
              getContainer().lookup(MavenSettingsBuilder.ROLE);
      Settings settings = mavenSettingsBuilder.buildSettings();
      MavenExecutionRequest request = new DefaultMavenExecutionRequest();
      request.setPom(pom);
      request.setLocalRepositoryPath(settings.getLocalRepository());
      MavenExecutionRequestPopulator populator =
              getContainer().lookup(MavenExecutionRequestPopulator.class);
      populator.populateDefaults(request);
      DefaultMaven maven = (DefaultMaven) getContainer().lookup(Maven.class);
      DefaultRepositorySystemSession repoSession =
              (DefaultRepositorySystemSession)
                  maven.newRepositorySession(request);
      LocalRepository localRepository = new LocalRepository(
              request.getLocalRepository().getBasedir());
      SimpleLocalRepositoryManagerFactory factory =
              new SimpleLocalRepositoryManagerFactory();
      LocalRepositoryManager localRepositoryManager =
              factory.newInstance(repoSession, localRepository);
      repoSession.setLocalRepositoryManager(localRepositoryManager);
      ProjectBuildingRequest buildingRequest =
              request.getProjectBuildingRequest()
                      .setRepositorySession(repoSession)
                      .setResolveDependencies(true);
      ProjectBuilder projectBuilder = lookup(ProjectBuilder.class);
      MavenProject project =
              projectBuilder.build(pom, buildingRequest).getProject();
      //noinspection deprecation - wait on maven-plugin-testing-harness update
      MavenSession session = new MavenSession(getContainer(), repoSession, 
              request, new DefaultMavenExecutionResult());
      session.setCurrentProject(project);
      session.setProjects(Collections.singletonList(project));
      request.setSystemProperties(System.getProperties());
      testMojo = (GenerateConfig) lookupConfiguredMojo(session,
              newMojoExecution("configure"));
      copyTestProjectResourcesToTarget(getContainer(), project, session);
  }
  </code></pre>
  
  <p><strong>[UPDATE 2017-07-27]</strong>: actually this now solves most of my problems.</p>
  
  <p>Only a couple of minor issues now:</p>
  
  <ol>
  <li>the code to grab the settings.xml is marked as <code>@Deprecated</code> so I assume there is a better way of doing it (using the <code>MavenSettingsBuilder.buildSettings()</code>)</li>
  <li>probably quite a lot of the setup code is duplicating process that occurs anyway when running in native maven, but is required to run with JUnit in IntelliJ. </li>
  </ol>
  
  <p><strong>[UPDATE 2017-08-01]</strong>: test now needs to access some property files which would be on the classpath in a live environment in the <code>target/classes</code> dir. </p>
  
  <p>Logically they are test resources in my maven-plugin project, so I have included them under the same directory as the test <code>pom.xml</code> in <code>src/test/resources/my-test-project</code> dir. </p>
  
  <p>That didn't work, so I also tried <code>src/test/resources/my-test-project/src/main/resources</code> but that's also not good.</p>
  
  <p>I am having a hard time establishing what exactly is on the plugin's classpath during the test, or working out how to cause it to be constructed correctly.</p>
  
  <p><strong>[UPDATE 2017-08-02]</strong>: although I've answered my own question (as opposed to extending this question), this whole thing isn't finished yet so I'm not marking this as answered quite yet.</p>
  
  <p>And just for the record, these are the dependencies required:</p>
  
  <pre><code>    &lt;dependency&gt;
          &lt;groupId&gt;org.junit.jupiter&lt;/groupId&gt;
          &lt;artifactId&gt;junit-jupiter-api&lt;/artifactId&gt;
          &lt;version&gt;5.0.0-M4&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
          &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
          &lt;version&gt;4.12.0-M4&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.maven&lt;/groupId&gt;
          &lt;artifactId&gt;maven-plugin-api&lt;/artifactId&gt;
          &lt;version&gt;3.5.0&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.maven.plugin-tools&lt;/groupId&gt;
          &lt;artifactId&gt;maven-plugin-annotations&lt;/artifactId&gt;
          &lt;version&gt;3.5&lt;/version&gt;
          &lt;scope&gt;provided&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.maven.plugin-testing&lt;/groupId&gt;
          &lt;artifactId&gt;maven-plugin-testing-harness&lt;/artifactId&gt;
          &lt;version&gt;3.3.0&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
          &lt;exclusions&gt;
              &lt;exclusion&gt;
                  &lt;groupId&gt;org.codehaus.plexus&lt;/groupId&gt;
                  &lt;artifactId&gt;plexus-container-default&lt;/artifactId&gt;
              &lt;/exclusion&gt;
          &lt;/exclusions&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.maven&lt;/groupId&gt;
          &lt;artifactId&gt;maven-core&lt;/artifactId&gt;
          &lt;version&gt;3.5.0&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.maven&lt;/groupId&gt;
          &lt;artifactId&gt;maven-compat&lt;/artifactId&gt;
          &lt;version&gt;3.5.0&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.twdata.maven&lt;/groupId&gt;
          &lt;artifactId&gt;mojo-executor&lt;/artifactId&gt;
          &lt;version&gt;2.3.0&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
          &lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;
          &lt;version&gt;3.0.2&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
  </code></pre>
  
  <p><strong>[UPDATE 2017-08-09]:</strong> </p>
  
  <p>I have to add some more functionality and discovered that the test was fine if the dependency it wanted to unpack was in the local repo already, but if not, it won't fetch it. </p>
  
  <p>I now need to determine how to instruct maven to fetch the dependency from the remote repo. </p>
  
  <p>I tried launching the dependency plugin and invoking <code>resolve</code> in the test setup, but it dies badly, I think there must be a simpler way.</p>