gpt4 book ai didi

java - 无法使用 PowerMock 模拟 java.lang.System#exit(int) 方法

转载 作者:行者123 更新时间:2023-12-01 14:33:43 24 4
gpt4 key购买 nike

我的应用程序有一个流程,最后是方法 System.exit(int)正在被调用。

我正在尝试通过使用 TestNG 运行测试来测试此流程。

但是,在运行测试时,虽然测试已完成,但我收到了这条奇怪的消息:

enter image description here

只是为了找到根本原因,我删除了 System.exit(int)从实际流程来看,测试按预期通过,所以这里的问题是 System.exit(int)方法。

为了解决这个问题,我试图模拟有问题的方法,但找不到正确的方法。这是我所做的

  • 我加了 java.lang.System.class@PrepareForTest在测试类中。
  • 已添加 PowerMockito.mockStatic(java.lang.System.class)在测试中
  • 我试图以两种方式模拟该方法:

    一种。
        PowerMockito.replace(PowerMockito.method(System.class, "exit", int.class))
    .with((proxy, method, args) -> null);

    当以这种方式运行时,看起来模拟不起作用,因为我在测试结束时收到了相同的消息,这在 System.exit(int)
  • 上没有应用任何模拟时也得到了相同的消息。

    enter image description here


    PowerMockito.doNothing().when(System.class, "exit", Mockito.any());

    通过这种方式,我在测试开始时遇到了这个异常:
    org.powermock.reflect.exceptions.MethodNotFoundException: No method found with name 'exit' with parameter types: [ <none> ] in class java.lang.System.

    我已经用这种方式 mock 了一些方法,不知道为什么 System.exit(int)它不工作。

    有任何想法吗?
    谢谢

    最佳答案

    有趣的问题,我也不知道,但显然,通过使用 SecurityManagers,不使用 Powermock 也是可能的。引自 original post :

    Today I was writing test for one of our command line tools, and I had this problem where the method dumping everything, which I really needed to be called since that’s the outcome I was checking, also called System.exit(). I had to find a way to test this anyway. I thought about using PowerMock and mocking system but that would have been complicated because I would have to find the exact class calling the System.exit(). So here is another solution to avoid the System.exit to exit (yes that’s possible I didn’t know about that either).

    The secrets lays in the SecurityManager mechanism of Java, this class not only allows you to check permissions, but also to check exit event. Therefore you can throw an exception if you want to stop the exit



    以下是我在 IJ 中测试的完整样本。请注意,样本应该是故意失败的:
    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);
    }
    }
    }

    关于java - 无法使用 PowerMock 模拟 java.lang.System#exit(int) 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54055881/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com