gpt4 book ai didi

java - 使 JUnit 测试在另一个线程中某处的 System.exit 上失败

转载 作者:行者123 更新时间:2023-11-30 11:32:11 26 4
gpt4 key购买 nike

我有一个多线程系统的功能测试。问题是系统使用 System.exit 所以我的 junit 测试没有发现这个错误。因此,如果在某个地方调用了 System.exit,我希望我的测试失败,即使在另一个线程中也是如此。

我用了Java: How to test methods that call System.exit()?以防止 JVM 在 System.exit 上停止并抛出 ExitException。我也用过 http://blog.cedarsoft.com/2011/12/junit-rule-fail-tests-on-exceptionsfailed-assertions-in-other-threads/收集此异常。我希望我的测试在 ExitException 失败后停止。但是这个异常只停止当前线程。我试图在抛出 ExitException 之前调用 junitThread.interrupt() 但它仅适用于简单测试。

如果我不能修改线程创建代码,我如何才能在任何线程中抛出 ExitException 时中断 junit 测试?

最佳答案

为什么调用 System.exit()?为什么它会在单元测试覆盖的级别调用 System.exit()

如果您想测试退出代码,您的测试可以生成一个进程并检查它是否已按计划退出。如果您想测试其他功能,请更好地构建您的应用程序,使被测代码不会产生如此讨厌的副作用。

但总的来说,我认为让单个线程调用 System.exit() 是不良架构的有力指标。如果任何线程可以立即终止整个应用程序而不给其他线程清理的机会,您可能很快就会遇到很多问题。

如果您的线程调用一些全局关闭处理程序(您可以在测试中覆盖它)而不是 System.exit(),您将不会在测试该功能时遇到问题。

更新:在处理遗留代码时,我的第一步是将 System.exit() 隔离到可以在测试中替换它的地方。例如。创建一个这样的类:

// "Singleton" with replaceable instance
public class ShutdownHandler {
private static ShutdownHandler instance = new ShutdownHandler();

public static ShutdownHandler getInstance() {
return instance;
}

public synchronized void shutdown() {
// default implementation
System.exit();
}

public static void setInstance(ShutdownHandler newInstance) {
// (probably also check that this is only called in a test environment)
instance = newInstance;
}
}

然后将所有 System.exit() 调用替换为 ShutdownHandler.getInstance().shutdown()。这根本不会改变应用程序的功能。 但是现在您可以将测试中的 ShutdownHandler 实例替换为设置一些标志 + 抛出异常而不是退出的实现 - 然后您的测试可以检查该标志以确定应用程序是否会退出。

我还可以推荐 Robert C. Martin 的“Working Effectively With Legacy Code”,以获得有关如何将旧的困惑变成可管理的东西的更多想法。

关于java - 使 JUnit 测试在另一个线程中某处的 System.exit 上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16787343/

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