2017-01-23 88 views
2

我有一个庞大的Maven多项目构建版本,单元测试主要使用PowerMock,版本为1.6。 2。我决定整合JaCoCo,所以我们可以开始发布我们的代码覆盖率指标。 JaCoCo的最新版本0.7.8需要PowerMock 1.6.6,所以我升级了我的版本。从PowerMock 1.6.2升级到1.6.6以集成JaCoCo 0.7.8后,“whenNew”调用导致空值

我现在看到一些错误的行为与“whenNew”调用有关,该调用在代码库中的所有测试中都会发生变化。

的 “whenNew()” 电话中的问题是这样的:

PowerMockito.whenNew(BlahBlah.class) 
      .withArguments(any(SomeClass.class)) 
      .thenReturn(blahBlahInstance); 

随着PowerMock 1.6.2,这是工作的罚款。当我升级到1.6.6时,为了做到这一点,我必须做出两个改变,一个是可以接受的,但是很烦人(因为我不知道为什么需要),另一个是不可接受的。

可接受的更改是在班级顶部的“@PrepareForTest”注释。使用PowerMock 1.6.2,这个列表只用于列出呼叫“new BlahBlah(...)”的类别,而且工作正常。为了让这个工作(除了下一个更改),我还必须在该列表中添加“BlahBlah.class”。我可以接受这一点,但如果我对清单上的内容有清晰的说明,这将非常有帮助。

第二个不可接受的更改是我必须将“.withArguments(any(SomeClass.class))”更改为“.withAnyArguments()”。我也试过“withArguments(anyObject())”,那也失败了。

更新

请注意,我用的Mockito核心的19年1月10日的版本。我从https://github.com/powermock/powermock/wiki/MockitoUsage#supported-versions看到,PowerMock 1.6.6(1.6.2+)支持该版本的mockito-core。

+0

你有没有得到解决方案 –

+0

是的。如果您仍有问题,请发布单独的问题。 –

回答

0

所有关于你的声明

JaCoCo,0.7.8的最新版本首先,需要PowerMock 1.6.6

JaCoCo不需要PowerMock并没有什么特殊的JaCoCo PowerMock为0.7.8。截至今日0.7.8是JaCoCo的最新发布版本。

我猜你的说法是一种误解是来自阅读https://github.com/powermock/powermock/wiki/Code-coverage-with-JaCoCo,其中规定

JaCoCo离线仪器仪表只适用于PowerMock版本1.6.6和上部。

根据https://github.com/powermock/powermock/blob/master/changelog.txt

更改日志1.6。6(2016年11月4日)

  • 固定#645 jacoco离线仪器仪表不相容powermock字节码操作使用@SuppressStaticInitializationFor

即有修复只在一个特定的情况下。在其他情况下,早期版本的PowerMock已经使用脱机工具与早期版本的JaCoCo一起工作。

然后根据PowerMock升级到1.6.6后,您的状态的描述,但是其他变化之前,试图建立一个Minimal, Complete, and Verifiable example

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>org.example</groupId> 
    <artifactId>example</artifactId> 
    <version>1.0-SNAPSHOT</version> 

    <properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <maven.compiler.source>1.8</maven.compiler.source> 
    <maven.compiler.target>1.8</maven.compiler.target> 

    <powermock.version>1.6.6</powermock.version> 
    <jacoco.version>0.7.8</jacoco.version> 
    </properties> 

    <dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.12</version> 
     <scope>test</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-module-junit4</artifactId> 
     <version>${powermock.version}</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-api-mockito</artifactId> 
     <version>${powermock.version}</version> 
     <scope>test</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.jacoco</groupId> 
     <artifactId>org.jacoco.agent</artifactId> 
     <classifier>runtime</classifier> 
     <version>${jacoco.version}</version> 
     <scope>test</scope> 
    </dependency> 
    </dependencies> 

    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-surefire-plugin</artifactId> 
     <version>2.18.1</version> 
     <configuration> 
      <systemPropertyVariables> 
      <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile> 
      </systemPropertyVariables> 
     </configuration> 
     </plugin> 
     <plugin> 
     <groupId>org.jacoco</groupId> 
     <artifactId>jacoco-maven-plugin</artifactId> 
     <version>${jacoco.version}</version> 
     <executions> 
      <execution> 
      <id>default-instrument</id> 
      <goals> 
       <goal>instrument</goal> 
      </goals> 
      </execution> 
      <execution> 
      <id>default-restore-instrumented-classes</id> 
      <goals> 
       <goal>restore-instrumented-classes</goal> 
      </goals> 
      </execution> 
      <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>report</goal> 
      </goals> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
    </build> 

</project> 

src/main/java/org/example/BlahBlah.java

package org.example; 

public class BlahBlah { 

    private final SomeClass c; 

    public BlahBlah(SomeClass c) { 
    this.c = c; 
    } 

    public String run() { 
    return c.toString(); 
    } 
} 

src/main/java/org/example/SomeClass.java

package org.example; 

public class SomeClass { 

    private final String s; 

    public SomeClass(String s) { 
    this.s = s; 
    } 

    @Override 
    public String toString() { 
    return s; 
    } 

} 

src/main/java/org/example/Example.java

package org.example; 

public class Example { 

    public String fun() { 
    return new BlahBlah(new SomeClass("Hello World")).run(); 
    } 

} 

src/test/java/org/example/ExampleTest.java

package org.example; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import static org.junit.Assert.assertEquals; 
import static org.mockito.Matchers.any; 

@PrepareForTest({Example.class}) 
@RunWith(PowerMockRunner.class) 
public class ExampleTest { 

    @Test 
    public void test() throws Exception { 
    BlahBlah e = new BlahBlah(new SomeClass("Hello PowerMock")); 
    PowerMockito.whenNew(BlahBlah.class) 
     .withArguments(any(SomeClass.class)) 
     .thenReturn(e); 
    assertEquals("Hello PowerMock", new Example().fun()); 
    } 

} 

mvn clean verify 

的作品就好了。所以在你的描述中应该有些东西是错过的,以便真实地再现你的情况。希望这会有所帮助,至少在此基础上构建更好的再现器。

此外:尝试解耦JaCoCo与PowerMock升级的整合流程 - 也许这种升级是有问题的,而不是JaCoCo的整合。

+0

如果说实话,在PowerMock 1.6.6之前,添加到'@ PrepareForTest'的所有类由于我们在JaCoCo问题中讨论的问题而没有覆盖。但是在抛出异常时,它也是'@ SuppressStaticInitializationFor',JaCoCo和TestNG的问题。 –

0

对于我的具体问题,事实证明,这是不工作的唯一地方是当实际的“SomeClass”参数为空,这是不匹配“any(SomeClass.class)”。在这些情况下,我必须将该条款更改为“withAnyArguments()”。

相关问题