测试 java 程序是不是调用 System.exist - 不退出 Junit

Posted

技术标签:

【中文标题】测试 java 程序是不是调用 System.exist - 不退出 Junit【英文标题】:Testing if a java program calls System.exist - without exiting Junit测试 java 程序是否调用 System.exist - 不退出 Junit 【发布时间】:2019-10-15 09:24:27 【问题描述】:

我正在尝试使用 Junit 测试文件处理程序。在某些情况下,程序应该打印一个错误并完成它的运行。但是,使用“System.exit(-1)”会导致程序退出整个 Junit 测试。 有什么办法可以避免吗?

我可以打印错误然后return null,但是我觉得它很不雅。

    private List<String> parseData(String[] args)
        if (args.length != 2)
            System.err.println(ERROR + INPUT_ERROR + "\n");
            System.exit(EXIT_CODE);

有没有办法检查程序是否调用“System.exit”而不关闭它? 谢谢。

【问题讨论】:

Preventing System.exit() from API的可能重复 只要抛出一个异常。 【参考方案1】:

我认为使用 System.exit 来验证输入参数更加不雅。 为什么不直接抛出一个异常,让这个方法的调用者来处理呢?

【讨论】:

你说得对,谢谢。这确实更优雅。 如果它是关于与操作系统通信,即用于脚本,异常对你没有任何好处。标准方法是退出代码,在这种情况下,恕我直言,可以测试是否返回了正确的代码。退出代码是已发布界面的一部分。【参考方案2】:

虽然我认为 AdrianM 的解决方案是理想的解决方案,但您也可以通过模拟来解决这个问题。

选项一:使用模拟框架,例如 PowerMock,它可以让您模拟静态方法,这样您就可以让 System.exit 什么都不做。

选项二:使用依赖注入和任何模拟框架。创建这个接口和实现类:

public interface SystemExit 
    void exit(int code);


public class SystemExitImpl implements SystemExit 
    public void exit(int code) 
        System.exit(code);
    

然后,使包含parseData 的类将SystemExit 作为构造函数参数并将其存储在成员变量中(或者为成员变量设置一个setter,让您在构造后对其进行设置)。在您的生产代码中,传递SystemExitImpl。在您的测试中,为SystemExit 创建一个模拟并通过它。

【讨论】:

以上是关于测试 java 程序是不是调用 System.exist - 不退出 Junit的主要内容,如果未能解决你的问题,请参考以下文章

Java应用中使用ShutdownHook友好地清理现场(转)

java 无法启动该应用程序,如何解决?

在python程序中调用java代码

如何测试 Json.parser 不是用 mockito java 调用的?

测试一个函数是不是被调用

如何测试我的 java 应用程序是不是可以成功处理 Tomcat 服务器上的低内存/CPU 资源?