java - 使用 PowerMockito 模拟静态方法

标签 java junit mockito powermockito

我正在使用 PowerMockito 模拟静态方法以获得更好的行覆盖率。测试通过,但 Cobertura 仍将返回线显示为红色。我不确定我是否以错误的方式使用 PowerMockito。有什么线索吗?

MUT

 public static Object getBean( String beanName ) {
    return AppContext.getApplicationContext().getBean( beanName );
}

Junit测试

@RunWith ( PowerMockRunner.class )
@PrepareForTest ( {AppContext.class} )

private ApplicationContext applicationContext;

@Test
public void testGetBean() throws Exception {
    String beanName = "junitBean";
    applicationContext = Mockito.mock(ApplicationContext.class);

    PowerMockito.mockStatic(AppContext.class);

    AppContext.setApplicationContext(applicationContext);
    PowerMockito.when(AppContext.getApplicationContext()).thenReturn(applicationContext);
    PowerMockito.when(AppContext.getApplicationContext().getBean(beanName)).thenReturn(Object.class);

    AppContext.getBean(beanName);
}

最佳答案

要模拟静态方法,PowerMock 必须在编译类后修改 Java 字节代码。代码覆盖工具以相同的方式工作 - 它们“检测”(谷歌“字节码检测”)字节码,以收集有关已运行的代码行的信息。

鉴于这里有两件事根据自己的需要修改已经编译的代码,因此它们不能很好地协同工作也就不足为奇了。事实上,其他覆盖工具也存在同样的问题,例如this issue在 PowerMock GitHub 页面上。

正是因为这样的原因,模拟静态方法是一个坏主意,只有在非常特殊的情况下才应该这样做。在大多数情况下,您可以将静态方法调用包装在接口(interface)中并将接口(interface)的实例传递给被测对象,或者更好(如果代码在您的控制之下)删除静态方法并将其替换为实例方法。

您还可以将 ApplicationContext 实例直接传递到被测类的构造函数中。

关于java - 使用 PowerMockito 模拟静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39600021/

相关文章:

java - 在测试中使用 DateTimeUtils.setCurrentMillisFixed 是否安全?

java - JUnit 测试 Controller 错误

java - Spring 测试 DBunit 警告

java - 为什么 Mockito.verify 未能通过与我放置的测试不同的测试?

java PowerMockito 忽略方法调用

java - 为什么我的多态父类从自身内部调用子类方法?

java - 使用 java 执行 imagemagick 命令没有输出

java - 如何在 Java 代码中使用 WSDL 文件中的用户定义数据类型?

java - 设置 JAVA_HOME 时出错

java - 何时使用 Mockito.verify()?