2011-10-13 45 views
3

有没有办法编写一个检查Maven依赖关系的测试?验证Maven构建中的依赖关系

在我们的项目中,我们发现了以下问题:

  • 项目的某些部分使用commons-io:commons-io,他人使用org.apache.commons:commons-io

  • 依赖的错误版本,使用

  • stax使用版本1.0-21.0.1。使用自动依赖关系解析,1.0-2获胜。

所以,我想要的是编写测试用例这需要当前依赖关系树作为输入,并运行一对夫妇检查就可以了。那可能吗?

回答

1
@Test 
public void testCommonsIo() throws Exception { 
    assertDependencyVersion("commons-io", "commons-io", "2.0"); 
} 

private void assertDependencyVersion(final String groupId, 
     final String artifactId, final String expectedVersion) 
     throws IOException { 

    final StringBuilder sb = new StringBuilder("/META-INF/maven/"); 
    sb.append(groupId).append("/").append(artifactId); 
    sb.append("/pom.properties"); 
    final String resourcePath = sb.toString(); 

    final InputStream propertiesStream = this.getClass() 
     .getResourceAsStream(resourcePath); 
    assertNotNull("no dependency found: " + groupId + ":" + artifactId, 
     propertiesStream); 

    final Properties properties = new Properties(); 
    properties.load(propertiesStream); 

    assertEquals("group", groupId, properties.getProperty("groupId")); 
    assertEquals("artifact", artifactId, properties.getProperty("artifactId")); 
    assertEquals("version", expectedVersion, properties.getProperty("version")); 
} 

也检查this answer


这里是StAX的和其他依赖断言方法不包含pom.properties只是manifest.mf。如果有很多assertDependencyByMetaInf调用,也许值得缓存Properties实例。

@Test 
public void testStaxDependency() throws Exception { 
    assertDependencyByMetaInf("StAX", "1.0.1"); 
} 

private void assertDependencyByMetaInf(final String specTitle, 
     final String expectedSpecVersion) throws IOException { 
    final ClassLoader cl = this.getClass().getClassLoader(); 

    final String resourcePath = "META-INF/MANIFEST.MF"; 
    final Enumeration<URL> resources = cl.getResources(resourcePath); 

    boolean found = false; 
    while (resources.hasMoreElements()) { 
     final URL url = resources.nextElement(); 
     final InputStream metaInfStream = url.openStream(); 

     final Properties metaInf = new Properties(); 
     metaInf.load(metaInfStream); 

     final String metaInfSpecTitle = 
      metaInf.getProperty("Specification-Title"); 
     if (!specTitle.equals(metaInfSpecTitle)) { 
      continue; 
     } 

     final String specVersion = 
      metaInf.getProperty("Specification-Version"); 
     assertEquals("version mismatch for " + specTitle, 
      expectedSpecVersion, specVersion); 
     found = true; 
    } 
    assertTrue("missing dependency: " + specTitle, found); 
} 
+0

-1,我只检查了所有的JAR文件包含神器本身pom.properties文件。没有包括依赖关系。 –

+0

传递依赖也在类路径上,所以'getResourceAsStream'找到他们的'pom.properties'。 – palacsint

+0

啊,我明白了。改变了我的投票。注意:来自Maven Central的一些JAR没有pom.properties条目:-(例如stax-api(http://search.maven.org/#artifactdetails%7Cstax%7Cstax-api%7C1.0.1%7Cjar) –

0

继从palacsint的建议,这里是另一种方法:计算一类是在类路径上的频率和打印网址,如果有不止一个。

private void assertOnceOnClassPath(String resourcePath) throws IOException { 
    ClassLoader cl = getClass().getClassLoader(); 

    Enumeration<URL> resources = cl.getResources(resourcePath); 
    List<URL> urls = new ArrayList<URL>(); 
    while(resources.hasMoreElements()) { 
     URL url = resources.nextElement(); 
     urls.add(url); 
    } 

    if(urls.size() != 1) { 
     fail("Expected exactly 1 item:\n" + StringUtils.join(urls, "\n")); 
    } 
}