Can';t mock java.lang.System#exit(int)方法与PowerMock
我的应用程序有一个流,在它的最后调用方法Can';t mock java.lang.System#exit(int)方法与PowerMock,java,testng,powermock,powermockito,Java,Testng,Powermock,Powermockito,我的应用程序有一个流,在它的最后调用方法System.exit(int) 我试图通过使用TestNG运行测试来测试这个流 然而,在运行测试时,我收到了一条奇怪的消息,尽管测试已经完成: 为了找到根本原因,我从实际流中删除了System.exit(int),测试按预期通过,因此这里的问题是System.exit(int)方法 为了解决这个问题,我试图模仿这个有问题的方法,但找不到正确的方法。这就是我所做的 我在tests类的@PrepareForTest下添加了java.lang.System.
System.exit(int)
我试图通过使用TestNG运行测试来测试这个流
然而,在运行测试时,我收到了一条奇怪的消息,尽管测试已经完成:
为了找到根本原因,我从实际流中删除了System.exit(int)
,测试按预期通过,因此这里的问题是System.exit(int)
方法
为了解决这个问题,我试图模仿这个有问题的方法,但找不到正确的方法。这就是我所做的
@PrepareForTest
下添加了java.lang.System.class
PowerMockito.mockStatic(java.lang.System.class)
org.powermock.reflect.exceptions.MethodNotFoundException: No method found with name 'exit' with parameter types: [ <none> ] in class java.lang.System.
org.powermock.reflect.exceptions.MethodNotFoundException:在类java.lang.System中找不到名为“exit”且参数类型为[]的方法。
我已经以这种方式模拟了一些方法,不知道为什么使用System.exit(int)
它不起作用
有什么想法吗?
谢谢有趣的问题,我也不知道,但显然,这是不需要使用Powermock,通过使用SecurityManager就可以实现的。引述: 今天我在为我们的一个命令行工具编写测试,我 这个问题在哪里的方法倾销一切,我真的 需要打电话,因为这也是我检查的结果 调用了System.exit()。无论如何,我必须找到一种方法来测试这个。我 曾考虑过使用PowerMock和mocking系统,但那会 这很复杂,因为我必须找到确切的类调用 返回System.exit()。因此,这里有另一个解决方案来避免 System.exit到exit(是的,这是可能的,我不知道 要么) 秘密在于Java的SecurityManager机制,这个类 不仅允许您检查权限,还允许您检查退出 事件因此,如果要停止该进程,可以抛出异常 出口 下面是我在IJ测试的完整样本。请注意,该样品应故意不合格,原因如下:
java.lang.AssertionError:
Expected: is <10>
but: was <5>
Expected :is <10>
Actual :<5>
java.lang.AssertionError:
预期:是吗
但是:是吗
预期:是吗
实际:
package.com.example;
导入org.junit.Test;
导入java.security.Permission;
导入静态org.hamcrest.Matchers.is;
导入静态org.junit.Assert.assertThat;
导入静态org.junit.Assert.fail;
公共类SystemExitSet{
@试验
公共无效应使用SpecificCode()退出{
//保存初始安全管理器(可能为空)
SecurityManager initialSecurityManger=System.getSecurityManager();
试一试{
//设置安全管理器
System.setSecurityManager(新的NoExitSecurityManager());
//执行测试中的代码
新建MyClass()。退出(5);
//确保这一点不是偶然达到的
失败(“应该抛出ExitException”);
}捕获(出口){
//验证退出代码
断言(E.Stand,(10));//我不认为这是一个好主意。你应该认真考虑重新设计你的系统,只调用你的main方法中的“代码>系统。退出< /代码>,没有别的地方。我不能改变这个代码,我必须在检查、Stuto.Ext()之后找到模拟问题的解决方案。仅在应用程序末尾的一个位置使用!不确定在调用System.exit()后,为什么会将测试显示为“Not started”(如上图所示)。当删除System.exit()时测试成功通过。所以你的问题已经解决了,不是吗?一点也没有。我已经编辑了这个问题。希望现在问题更清楚。非常确定很多ppl都将此作为调查的基础。我想这让我在这个主题上的研究减少了一半。干杯。
org.powermock.reflect.exceptions.MethodNotFoundException: No method found with name 'exit' with parameter types: [ <none> ] in class java.lang.System.
java.lang.AssertionError:
Expected: is <10>
but: was <5>
Expected :is <10>
Actual :<5>
package com.example;
import org.junit.Test;
import java.security.Permission;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
public class SystemExitTest {
@Test
public void shouldExitWithSpecificCode() {
//save the initial security manager (probably null)
SecurityManager initialSecurityManger = System.getSecurityManager();
try {
// set security manager
System.setSecurityManager(new NoExitSecurityManager());
// execute code under test
new MyClass().exit(5);
// ensure this point is not reached by any chance
fail("Should've thrown ExitException");
} catch (ExitException e) {
// validate exit code
assertThat(e.status, is(10)); // <== this fails on purpose
} finally {
// restore initial security manager (otherwise a new ExitException will be thrown when the JVM will actually exit)
System.setSecurityManager(initialSecurityManger);
}
}
// class under test
public static class MyClass {
public void exit(int code) {
System.exit(code);
}
}
// exception to be thrown by security manager when System.exit is called
public static class ExitException extends SecurityException {
public final int status;
public ExitException(int status) {
this.status = status;
}
}
// custom security manager
public static class NoExitSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
}
@Override
public void checkPermission(Permission perm, Object context) {
}
@Override
public void checkExit(int status) {
super.checkExit(status);
throw new ExitException(status);
}
}
}