如何使用JUnit4测试Maven插件

5

我正在编写一个Maven插件,想编写一些JUnit测试。我遵循了Maven Plugin Testing中的说明。不幸的是,在我可以配置或调用任何东西之前,我一直在测试设置期间收到异常。

这是我的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();
    }

}

以下是异常的堆栈跟踪:

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)

有关如何使其正常工作的任何想法吗?

你解决了吗? - Adam Siemion
4个回答

3
同时遇到了这个问题。该规则失败,因为它实例化了AbstractMojoTestCase的一个匿名实现,然后试图在此处创建加载数据的输入流:InputStream is = getClass().getResourceAsStream( "/" + getPluginDescriptorLocation() );。这个getPluginDescriptorLocation()只是一个硬编码的文件字符串"META-INF/maven/plugin.xml"
我通过添加以下依赖项解决了这个问题:
<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-compat</artifactId>
  <version>3.5.0</version>
</dependency>

我不确定为什么这样可以解决问题。文件仍然不存在(我已经检查了原始源和目标目录,但它们都没有)。因此,需要进行额外的搜索以弄清楚为什么这样可以解决问题。
以下是我的依赖关系供参考。
<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>

1

遇到了同样的问题。通过添加正确的依赖项解决了它。重要的是,由harness 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>

而你的测试类应该长这样

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 ...
  }
}

希望这能对其他遇到同样问题的人有所帮助。

0

通过添加Maven兼容性库,已解决此问题:

        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-compat</artifactId>
            <version>${maven.version}</version>
            <scope>test</scope>
        </dependency>

-1

加载POM文件看起来不太好:

以下代码来自示例:

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

这就是你所拥有的:

File pom = new File(POM_FILE_NAME);

除此之外,您还有一个看起来像这样的不同位置:

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

但是pom文件的位置应该是:

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

是的,这个例子无法编译。但这并不重要。如果你查看堆栈跟踪,你会发现它在更早的时候就崩溃了。测试方法从未被执行。 - BetaRide
那意味着什么?这段代码没有被执行。是 MojoRule 设置导致了崩溃。 - BetaRide
你的POM文件真正的位置在哪里?你所使用的路径看起来不正确,因为它以“/…”开头。 - khmarbaise
5
MojoRule类上不存在getTestFile方法。甚至有一个错误指出示例文档是错误的。 - DB5
更糟糕的是,这个漏洞已经被关闭了,而不是像评论中所说的那样被修复了! - Mansour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接