简体   繁体   English

如何使用JUnit4测试maven插件

[英]How to test a maven plugin using JUnit4

I'm writing a maven plugin and want to write some JUnit tests. 我正在写一个maven插件,想写一些JUnit测试。 I followed the description in Maven Plugin Testing . 我按照Maven Plugin Testing中的描述进行了操作。 Unfortunately I keep getting an Exception during set-up of the test, before I can configure or invoke anything. 不幸的是,在我可以配置或调用任何东西之前,我在测试设置期间一直遇到异常。

This is my JUnit test code: 这是我的JUnit测试代码:

public class ResetMojoTest {

    private static final String POM_FILE_NAME = "/path/to/pom.xml"; 

    @Rule
    public MojoRule rule = new MojoRule();

    @Test
    public void testSomething()
        throws Exception
    {
        File pom = new File(POM_FILE_NAME);
        Assert.assertNotNull( pom );
        Assert.assertTrue( pom.exists() );

        ResetMojo resetMojo = (ResetMojo) rule.lookupMojo( "touch", pom );
        Assert.assertNotNull( resetMojo );
        resetMojo.execute();
    }

}

And this is the stack trace of the exception: 这是异常的堆栈跟踪:

java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
    at org.apache.commons.io.input.BOMInputStream.getBOM(BOMInputStream.java:175)
    at org.apache.commons.io.input.BOMInputStream.getBOMCharsetName(BOMInputStream.java:201)
    at org.apache.commons.io.input.XmlStreamReader.doRawStream(XmlStreamReader.java:412)
    at org.apache.commons.io.input.XmlStreamReader.<init>(XmlStreamReader.java:206)
    at org.apache.commons.io.input.XmlStreamReader.<init>(XmlStreamReader.java:171)
    at org.apache.commons.io.input.XmlStreamReader.<init>(XmlStreamReader.java:140)
    at org.apache.maven.plugin.testing.AbstractMojoTestCase.setUp(AbstractMojoTestCase.java:119)
    at org.apache.maven.plugin.testing.MojoRule$2.evaluate(MojoRule.java:299)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)

Any ideas about how to get this working? 关于如何使这个工作的任何想法?

Also experiencing this issue. 也遇到了这个问题。 The mojo rule fails, because it instantiates a an anonymous implementation of AbstractMojoTestCase , which then looks for which then attempts to create an input stream loading data here: InputStream is = getClass().getResourceAsStream( "/" + getPluginDescriptorLocation() ); mojo规则失败,因为它实例化了一个AbstractMojoTestCase的匿名实现,然后查找然后尝试创建一个输入流来加载数据: InputStream is = getClass().getResourceAsStream( "/" + getPluginDescriptorLocation() ); . This ( getPluginDescriptorLocation() ) is just a hard-coded file string "META-INF/maven/plugin.xml" . 这个( getPluginDescriptorLocation() )只是一个硬编码的文件字符串"META-INF/maven/plugin.xml"

I resolved this by adding the following dependency: 我通过添加以下依赖项解决了这个问题:

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-compat</artifactId>
  <version>3.5.0</version>
</dependency>

I'm not sure why this fixes the issue. 我不确定为什么这会解决这个问题。 The file still doesn't exist (I've checked both original sources and target directories and it's not in either). 该文件仍然不存在(我已检查过原始源和target目录,但它们都没有)。 So additional searching will be needed to figure out why this works. 因此需要进一步搜索以找出其工作原理。

Here's my dependencies for reference. 这是我的依赖项供参考。

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-plugin-api</artifactId>
  <version>3.5.0</version>
</dependency>
<dependency>
  <groupId>org.twdata.maven</groupId>
  <artifactId>mojo-executor</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>org.apache.maven.plugin-tools</groupId>
  <artifactId>maven-plugin-annotations</artifactId>
  <version>3.5</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.eclipse.aether</groupId>
  <artifactId>aether-api</artifactId>
  <version>1.1.0</version>
</dependency>
<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-core</artifactId>
  <version>3.5.0</version>
</dependency>
<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-compat</artifactId>
  <version>3.5.0</version>
</dependency>
<!--Test Dependencies-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.apache.maven.plugin-testing</groupId>
  <artifactId>maven-plugin-testing-harness</artifactId>
  <version>3.3.0</version>
  <scope>test</scope>
</dependency>

Got the same issue. 得到了同样的问题。 Solved it by adding the right dependencies. 通过添加正确的依赖项来解决它。 Important is that the dependencies marked as provided by the harness maven plugin are added to test scope: 重要的是,标记为由tape maven插件提供的依赖项被添加到测试范围:

<properties>
  <dependency.maven.version>3.3.9</dependency.maven.version>
  <!-- and others -->
</properties>

<dependencies>
  <!-- your dependencies -->

  <!-- maven plugin dependencies -->
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-plugin-api</artifactId>
    <version>${dependency.maven.version}</version>
  </dependency>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-core</artifactId>
    <version>${dependency.maven.version}</version>
  </dependency>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-model</artifactId>
    <version>${dependency.maven.version}</version>
  </dependency>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-artifact</artifactId>
    <version>${dependency.maven.version}</version>
  </dependency>

  <!-- test dependencies -->
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${dependency.junit.version}</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.maven.plugin-testing</groupId>
    <artifactId>maven-plugin-testing-harness</artifactId>
    <version>3.3.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-aether-provider</artifactId>
    <version>${dependency.maven.version}</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-compat</artifactId>
    <version>${dependency.maven.version}</version>
    <scope>test</scope>
  </dependency>

  <!-- provided maven dependencies -->
  <dependency>
    <groupId>org.apache.maven.plugin-tools</groupId>
    <artifactId>maven-plugin-annotations</artifactId>
    <version>3.3</version>
    <scope>provided</scope>
  </dependency>

</dependencies>

And your Test class should look like 你的Test类看起来应该是这样的

public class YourMojoTest {

  @Rule
  public MojoRule rule = new MojoRule();

  @Test
  public void shouldExecuteMojo() throws Exception {
    // given
    File testPom = new File(PlexusTestCase.getBasedir(), "src/test/resources/pom.xml");

    final Properties properties = new Properties();
    final MavenProject mavenProject = Mockito.mock(MavenProject.class);
    Mockito.when(mavenProject.getProperties()).thenReturn(properties);

    // when
    YourMojo mojo = (YourMojo) rule.lookupMojo("fetch", testPom);
    assertNotNull(mojo);
    mojo.setProject(mavenProject);
    mojo.execute();

    // then
    // do your tests ...
  }
}

Hope this helps for other struggling with the same issue 希望这有助于其他人在同样的问题上挣扎

The loading of the POM file does not look good: 加载POM文件看起来不太好:

The following code is from the examples: 以下代码来自示例:

File pom = rule.getTestFile( "src/test/resources/unit/project-to-test/pom.xml" );

and this is what you have: 这就是你拥有的:

File pom = new File(POM_FILE_NAME);

Apart from this you have a different location which looks like this: 除此之外,您还有一个不同的位置,如下所示:

private static final String POM_FILE_NAME = "/path/to/pom.xml"; 

But the location of the pom file should be: 但是pom文件的位置应该是:

private static final String POM_FILE_NAME = "src/test/resources/pom.xml"; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM