I am implementing some tests for an existing Java Swing application, so that I can safely refactor and extend the code without breaking anything. I started with some unit tests in JUnit, since that seems the simplest way to get started, but now my priority is to create some end-to-end tests to exercise the application as a whole.
I am starting the application afresh in each test by putting each test method in a separate test case, and using the fork="yes"
option in Ant's junit
task. However, some of the use cases I would like to implement as tests involve the user exiting the application, which results in one of the methods calling System.exit(0). This is regarded by JUnit as an error: junit.framework.AssertionFailedError: Forked Java VM exited abnormally
.
Is there a way to tell JUnit that exiting with a return code of zero is actually OK?
exit(0) method terminates JVM which results in termination of the currently running program too. Status is the single parameter that the method takes. If the status is 0, it indicates the termination is successful. Let's see practical implementations of System.
You actually can mock or stub out the System. exit method, in a JUnit test. Vote down reason: The problem with this solution is that if System. exit is not the last line in the code (i.e. inside if condition), the code will continue to run.
exit(0) : Indicates successful termination. exit(1) or exit(-1) or any non-zero value – indicates unsuccessful termination.
The main alternative is Runtime. getRuntime(). halt(0) , described as "Forcibly terminates the currently running Java virtual machine". This does not call shutdown hooks or exit finalizers, it just exits.
The library System Rules has a JUnit rule called ExpectedSystemExit. With this rule you are able to test code, that calls System.exit(...):
public class MyTest {
@Rule
public final ExpectedSystemExit exit = ExpectedSystemExit.none();
@Test
public void systemExitWithArbitraryStatusCode() {
exit.expectSystemExit();
/* the code under test, which calls System.exit(...)
* with an arbitrary status
*/
}
@Test
public void systemExitWithSelectedStatusCode0() {
exit.expectSystemExitWithStatus(0);
//the code under test, which calls System.exit(0)
}
}
System Rules needs at least JUnit 4.9.
Full disclosure: I'm the author of System Rules.
If anybody needs this functionality for JUnit 5, I've written an extension to do this. This is a simple annotation you can use to tell your test case to expect and exit status code or a specific exit status code.
For example, any exit code will do:
public class MyTestCases {
@Test
@ExpectSystemExit
public void thatSystemExitIsCalled() {
System.exit(1);
}
}
If we want to look for a specific code:
public class MyTestCases {
@Test
@ExpectSystemExitWithStatus(1)
public void thatSystemExitIsCalled() {
System.exit(1);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With