PowerMock ECLemma 覆盖问题
Posted
技术标签:
【中文标题】PowerMock ECLemma 覆盖问题【英文标题】:PowerMock ECLEmma coverage issue 【发布时间】:2014-06-15 07:19:49 【问题描述】:我们在 JUnit 中使用 EasyMock 和 PowerMock。使用的覆盖工具是 ECLEmma。使用 EasyMock,它以绿色正确显示覆盖范围(如已覆盖)。但是,对于使用 PowerMock 进行单元测试的代码,覆盖率显示为红色(未覆盖)。在网上阅读过类似的问题。但是,只是想检查是否有解决方案。
谢谢 文卡特斯
【问题讨论】:
把你的powermock测试逻辑放在测试包内的其他简单java类中,并从测试类中调用merhod,增加应用程序的代码覆盖率。 【参考方案1】:是的,有一个解决方案:
首先你必须添加这个maven依赖:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
然后,不要使用这个注解@RunWith(PowerMockRunner.class),只需像这样在Test类中添加一个@Rule:
public class Test
@Rule
public PowerMockRule rule = new PowerMockRule();
您可以在此博客中找到更多信息Make EclEmma test coverage work with PowerMock
【讨论】:
你能指导一下吗?***.com/questions/52064126/…【参考方案2】:这是一个已知问题:https://github.com/jayway/powermock/issues/422
而且已经很久了,不会很快修复的。
我建议你改用eCobertura。
【讨论】:
在切换之前请注意 eCobertura 的限制:bitbucket.org/jmhofer/ecobertura/… eCobertura 插件似乎不再维护 为了解决这个问题,我最终将所有使用PowerMocikito.staticMock
的测试拆分到单独的类文件中,这样覆盖问题就不会扩散到我的所有测试中。【参考方案3】:
这在我的项目中的大多数情况下都有效:
@Rule
public PowerMockRule rule = new PowerMockRule();
static
PowerMockAgent.initializeIfNeeded();
删除/评论 @RunWith(PowerMockRunner.class)
并在您的类路径中添加 powermock-module-javaagent-1.6.5.jar
后包括以下导入:
import org.junit.Rule;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.powermock.modules.agent.PowerMockAgent;
现在右键单击->Coverage As->Coverage Configurations 并在 Arguments 中添加以下行:
-ea -noverify -javaagent:path/to/powermock-module-javaagent-1.6.5.jar
点击应用->覆盖范围。
还要注意@Before
在这种情况下不起作用,因此您必须从标有@Before
的方法中添加标有@Test
的方法中的所有内容。
【讨论】:
【参考方案4】:我们有一个要模拟的静态类。使用模拟静态类,eclEmma 代码覆盖率插件在 Eclipse 中不起作用。所以我们所做的是,所以将 @RunWith(JUnit4.class) (而不是 @RunWith(PowerMockRunner.class) )放在类之前,并将以下几行放在类中
static
PowerMockAgent.initializeIfNeeded();
@Rule
public PowerMockRule rule = new PowerMockRule();
编译类并运行测试类。代码覆盖率适用于课堂。此更改仅在 Eclipse IDE 中。
编写测试用例后,我们将代码恢复正常。放置 @RunWith(PowerMockRunner.class) 而不是 @RunWith(JUnit4.class) 并在静态代码和 powermockrule 行上方注释。
【讨论】:
【参考方案5】:我已经设法使用 powermock-module-javaagent
使用 Jacoco 生成 PowerMock 覆盖范围。
只需确保将 powermock 代理放在 jacoco 代理之后:
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<argLine>$jacocoArgLine -javaagent:$settings.localRepository/org/powermock/powermock-module-javaagent/$powermock.version/powermock-module-javaagent-$powermock.version.jar -noverify</argLine>
...
如果你想看一个例子,看看这个项目:https://github.com/jfcorugedo/sonar-scanner
在这里您可以看到声纳考虑了静态方法和被 PowerMock 模拟的 new
语句:
如果您想模拟 new
statements,请确保使用 PowerMockRule
而不是 PowerMockRunner
。
看看this test
【讨论】:
【参考方案6】:更新 powermock 版本修复我的问题是支持版本的 maven 依赖
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.7.3</version>
<scope>test</scope>
</dependency>
希望对你有帮助!!!
【讨论】:
【参考方案7】:我遇到了同样的问题。所以,我更新了 powerMockito 版本。现在我使用的是 Power mock 1.7.4 版和 Jacoco 0.8.5 版。它甚至也在 eclipse 上工作。
【讨论】:
【参考方案8】:这里有一些更详细的全班答案。
需要注意的几点:
我必须使用spy
而不是mockStatic
我不得不将@PrepareForTest 移到方法级别。
正如其他答案中提到的那样,我还必须添加以下依赖项
org.powermock:powermock-module-junit4-rule-agent:2.0.9
以下是我的完整课程代码供参考:
import java.util.ArrayList;
import java.util.Arrays;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.agent.PowerMockAgent;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.opensource.dummy.config.DummyConfig;
import org.opensource.dummy.data.builder.DataBuilder;
import org.opensource.dummy.model.SampleRequest;
import org.opensource.dummy.model.SampleType;
import org.opensource.dummy.model.Item;
import org.opensource.dummy.model.RequestType;
@RunWith(JUnit4.class)
public class MockedDataSearchServiceHelperTest
static
PowerMockAgent.initializeIfNeeded();
@Rule
public PowerMockRule rule = new PowerMockRule();
@PrepareForTest( DummyConfig.class )
@SuppressWarnings("unchecked")
@Test
public void testSearchResponseValid() throws Exception
Item Item = DataBuilder.createItem("2024-01-24", "2024-12-25", "61ef8faebec3bb72fbcf336d", null);
SampleRequest sampleRequest = DataBuilder.createSampleRequest(Arrays.asList(Item),
DataBuilder.createDeliveryMetrics(1), null, RequestType.ITEM);
BoolQueryBuilder boolQueryBuilder = DataSearchServiceHelper.createCustomQuery(sampleRequest, Item);
SearchRequestBuilder searchRequestBuilder = PowerMockito.mock(SearchRequestBuilder.class);
ActionFuture<SearchResponse> actionFuture = PowerMockito.mock(ActionFuture.class);
Client client = PowerMockito.mock(Client.class);
PowerMockito.spy(DummyConfig.class);
PowerMockito.doReturn(client).when(DummyConfig.class, "getClient");
Mockito.when(client
.prepareSearch(new String[] "dummy" ))
.thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN))
.thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.setQuery(Mockito.any(QueryBuilder.class))).thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.execute()).thenReturn(actionFuture);
Mockito.when(actionFuture.actionGet()).thenReturn(new SearchResponse(null, null, 0, 0, 0, 0, null, null));
SearchResponse searchResponse = DataSearchServiceHelper.getSearchResponse(
new String[] "dummy" ,
boolQueryBuilder, DataBuilder.createDeliveryMetrics(1), RequestType.ITEM);
Assert.assertNotNull(searchResponse);
我希望这对某人有所帮助。
【讨论】:
【参考方案9】:对于模拟静态类,使用 @RunWith(PowerMockRunner.class)
并在 Eclipse 上运行“Coverage As JUnit 测试”确实会显示已覆盖的代码未覆盖,这显然是个问题。
要添加到上面的解决方案,在一个maven项目中,你可以试试这个..
在根pom.xml
中,为生成报告,添加html
作为cobertura-maven-plugin
中的格式。下面是它的外观。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
</configuration>
</plugin>
然后,转到您的类所在的模块并在 Eclipse Web 浏览器或您选择的一个中打开 target/site/cobertura/index.html
文件。您可以在那里找到覆盖范围信息。
【讨论】:
能否指导一下“Emma”代码覆盖率工具?以上是关于PowerMock ECLemma 覆盖问题的主要内容,如果未能解决你的问题,请参考以下文章