【问题标题】:How to test a maven plugin using JUnit4如何使用 JUnit4 测试 maven 插件
【发布时间】:2014-08-08 07:52:45
【问题描述】:

我正在编写一个 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)

关于如何使它工作的任何想法?

【问题讨论】:

  • 你解决了吗?

标签: java maven maven-plugin junit4


【解决方案1】:

也遇到了这个问题。 mojo 规则失败,因为它实例化了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>

我不确定为什么这可以解决问题。该文件仍然不存在(我已经检查了原始来源和target 目录,但两者都不存在)。因此,需要进行额外的搜索才能弄清楚为什么会这样。

这是我的依赖项供参考。

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

【讨论】:

    【解决方案2】:

    遇到同样的问题。通过添加正确的依赖项来解决它。重要的是标记为由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 ...
      }
    }
    

    希望这对其他在同一问题上苦苦挣扎的人有所帮助

    【讨论】:

      【解决方案3】:

      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"; 
      

      【讨论】:

      • 是的,该示例无法编译。但这无论如何都无关紧要。如果您查看堆栈跟踪,您会发现它崩溃得更早。测试方法永远不会执行。
      • 这意味着什么?此代码不会被执行。崩溃的是 MojoRule 设置。
      • 你的 pom 文件到底在哪里?您使用的路径看起来不对,因为它以 /..... 开头。
      • getTestFile 方法在MojoRule Class 上不存在。甚至还有bug 指出示例文档有误。
      • 更糟糕的是,该错误已关闭,并没有像 cmets 声称的那样修复!
      猜你喜欢
      • 1970-01-01
      • 2011-12-09
      • 2013-01-16
      • 2017-10-02
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 1970-01-01
      相关资源
      最近更新 更多