首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用System.exit来模拟PowerMockito?

如何用System.exit来模拟PowerMockito?
EN

Stack Overflow用户
提问于 2020-08-01 10:42:34
回答 1查看 2.1K关注 0票数 0

我希望对调用System.exit(-1)的Java代码进行单元测试,并希望它只做任何事情,而不是退出进程。其根本原因是,否则JaCoCo不能正常工作,项目指导方针希望看到这一行的内容。更改测试代码也不是一个选项。其他对系统的调用应该正常工作。PowerMockito 2.0.7已经在项目中使用了,在这里也应该使用。我现在的Java版本是Windows上的1.8.0_181。

我试过

代码语言:javascript
复制
PowerMockito.spy(System.class);
PowerMockito.doNothing().when(System.class, "exit", ArgumentMatchers.any(int.class));
//here comes the code under test that calls System.exit

它似乎不起作用,System.exit似乎退出了这个过程。它怎么能让这件事起作用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-01 12:13:52

我认为您应该替换示例代码中的两行代码。

代码语言:javascript
复制
PowerMockito.spy(System.class);
PowerMockito.doNothing.....

代码语言:javascript
复制
PowerMockito.mockStatic(System.class);

此更改在我的本地中有效,因为System.exit不执行任何操作,因为使用了模拟的静态方法。

另外,我希望您正在使用PrepareForTest注释。

代码语言:javascript
复制
@PrepareForTest(CLASS_UNDER_TEST)

间谍方法是调用真正的方法,并对非静态方法进行包装。由于静态方法需要模拟,所以应该使用mockStatic方法。

更新1

默认情况下,PowerMockito mockStatic方法为类中的所有静态方法创建模拟。我没有任何干净的溶液。但是,我可以提出一个看起来很难看但需要做的解决方案,即只模拟特定的静态方法,其余的方法正在调用实际的方法。PoweMockito的mockStatic方法在内部调用DefaultMockCreator来模拟静态方法。

代码语言:javascript
复制
@RunWith(PowerMockRunner.class)
public class StaticTest {

  @Test
  public void testMethod() throws Exception {

    // Get static methods for which mock is needed
    Method exitMethod = System.class.getMethod("exit", int.class);
    Method[] methodsToMock = new Method[] {exitMethod};

    // Create mock for only those static methods
    DefaultMockCreator.mock(System.class, true, false, null, null, methodsToMock);

    System.exit(-1); // This will be mocked
    System.out.println(System.currentTimeMillis()); // This will call up real methods
  }
}

根据PowerMockito文档,调用静态void方法的正确方法是-

代码语言:javascript
复制
PowerMockito.mockStatic(SomeClass.class);
PowerMockito.doNothing().when(SomeClass.class);
SomeClass.someVoidMethod();

参考- https://github.com/powermock/powermock/wiki/Mockito#how-to-stub-void-static-method-to-throw-exception

这应该会为特定的静态void方法创建模拟行为。不幸的是,这并不适用于System,因为System类是最终的。如果不是最后决定的话,这会奏效的。我试过了,我得到了一个例外-

代码语言:javascript
复制
org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class java.lang.System
Mockito cannot mock/spy because :
 - final class

密码-

代码语言:javascript
复制
@Test
public void testMethod() throws Exception {
    PowerMockito.mockStatic(System.class);
    PowerMockito.doNothing().when(System.class);
    System.exit(-1); // mockito error coming here

    System.exit(-1);
    System.currentTimeMillis();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63204305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档