使用PowerMockito模拟静态方法

时间:2016-09-20 17:08:33

标签: 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);
}

1 个答案:

答案 0 :(得分:1)

要模拟静态方法,PowerMock必须在编译后修改类的Java字节代码。代码覆盖工具以相同的方式工作 - 他们"仪器" (google for" bytecode instrumentation")字节码,以便收集有关已运行代码行的信息。

鉴于这里有两件事情根据自己的需要修改已编译的代码,因此它们不能很好地协同工作并不奇怪。实际上,其他覆盖工具具有相同的问题,例如PowerMock GitHub页面上的this issue

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

您也可以直接将ApplicationContext实例传递给正在测试的类的构造函数。