简体   繁体   English

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

[英]Make JUnit test fail on System.exit somewhere in another thread

I have a functional test of Multi-threading system. 我对多线程系统进行了功能测试。 The problem is that the system uses System.exit so my junit test doesn't catch this errors. 问题是系统使用System.exit,所以我的junit测试无法捕获此错误。 So I want my test fail if somewhere System.exit was called, even in another threads. 因此,我希望即使在其他线程中调用了System.exit,我的测试也会失败。

I used Java: How to test methods that call System.exit()? 我用过Java:如何测试调用System.exit()的方法? to prevent JVM stop on System.exit and throw ExitException instead. 以防止JVM在System.exit上停止并抛出ExitException。 Also I used http://blog.cedarsoft.com/2011/12/junit-rule-fail-tests-on-exceptionsfailed-assertions-in-other-threads/ to collect this exceptions. 我也使用http://blog.cedarsoft.com/2011/12/junit-rule-fail-tests-on-exceptionsfailed-assertions-in-other-threads/来收集此异常。 I want my test to stop after ExitException with fail. 我希望退出ExitException失败后停止测试。 But this exception stops only current thread. 但是此异常仅停止当前线程。 I tried to call junitThread.interrupt() before throwing ExitException but it is works perfectly only for simple tests. 我试图在抛出ExitException之前调用junitThread.interrupt(),但它仅适用于简单测试。

How can I break junit test on throwing ExitException in any thread if I can't modify thread creation code? 如果无法修改线程创建代码,如何在抛出任何线程异常时打破junit测试?

Why does it call System.exit() ? 为什么调用System.exit() And why does it call System.exit() at a level you're covering with your unit test? 为什么它会在单元测试涵盖的级别调用System.exit()

If you want to test the exiting code, your tests can spawn a process and check that it has exited as planned. 如果要测试退出的代码,则测试可以生成一个进程并检查它是否按计划退出。 If you want to test other functionality, better structure your application in such a way that the code under test doesn not have such nasty side effects. 如果要测试其他功能,请以一种更好的方式构造应用程序,使被测试的代码不会产生令人讨厌的副作用。

In general though, I'd say that having individual threads call System.exit() is a strong indicator of bad architecture. 不过,总的来说,我想说有单独的线程调用System.exit()可以很好地表明体系结构不良。 If any thread can instantly kill the entire appication without giving other threads a chance to clean up you'll likely run into quite some problems quite soon. 如果有任何线程可以立即杀死整个应用程序而没有给其他线程一个清理的机会,那么您很快就会遇到很多问题。

And if your threads call some global shutdown handler (that you can override in your tests) instead of System.exit() you won't have a problem testing that functionality. 而且,如果您的线程调用某些全局关闭处理程序(可以在测试中覆盖)而不是System.exit() ,则在测试该功能时不会有问题。

Update: When dealing with legacy code, my first step would be to isolate the System.exit() into a place where it can be replaced in tests. 更新:处理遗留代码时,我的第一步是将System.exit()隔离到可以在测试中将其替换的位置。 Eg create a class like this: 例如,创建一个这样的类:

// "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;
    }
}

Then replace all System.exit() calls with ShutdownHandler.getInstance().shutdown() . 然后用ShutdownHandler.getInstance().shutdown()替换所有System.exit()调用。 That won't change the application's functionality at all. 那根本不会改变应用程序的功能。 But now you can replace the ShutdownHandler instance in your tests with an implementation that sets some flag + throws an exception instead of exiting -- and your tests can then check that flag to determine whether the app would have exited. 但是现在您可以使用设置了某些标志+引发异常而不是退出的实现的实现替换测试中的ShutdownHandler实例,然后您的测试可以检查该标志以确定该应用是否已退出。

I can also recommend "Working Effectively With Legacy Code" by Robert C. Martin for more ideas on how to turn an old mess into something manageable. 我还可以推荐Robert C. Martin撰写的“有效使用旧版代码”,以获取有关如何将旧的混乱变成可管理的内容的更多想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM