सबसे समाधान होगा
- परीक्षण (विधि, संपूर्ण रन नहीं) को समाप्त करने का क्षण
System.exit()
कहा जाता है
- पहले से स्थापित की उपेक्षा करें
SecurityManager
- कभी-कभी परीक्षण ढांचे के लिए काफी विशिष्ट होते हैं
- प्रति परीक्षण के मामले में अधिकतम एक बार उपयोग करने के लिए प्रतिबंधित है
इस प्रकार, अधिकांश समाधान उन स्थितियों के लिए अनुकूल नहीं हैं जहाँ:
- कॉल करने के बाद साइड-इफेक्ट्स का सत्यापन किया जाना है
System.exit()
- एक मौजूदा सुरक्षा प्रबंधक परीक्षण का हिस्सा है।
- एक अलग परीक्षण रूपरेखा का उपयोग किया जाता है।
- आप एक ही परीक्षण के मामले में कई सत्यापन करना चाहते हैं। यह कड़ाई से अनुशंसित नहीं हो सकता है, लेकिन कई बार बहुत सुविधाजनक हो सकता है, विशेष रूप से संयोजन में
assertAll()
उदाहरण के लिए, के ।
मैं अन्य उत्तरों में प्रस्तुत किए गए मौजूदा समाधानों द्वारा लगाए गए प्रतिबंधों से खुश नहीं था, और इस तरह अपने आप कुछ के साथ आया।
निम्न वर्ग एक विधि प्रदान करता है assertExits(int expectedStatus, Executable executable)
जो System.exit()
निर्दिष्ट status
मूल्य के साथ कहा जाता है , और परीक्षण इसके बाद भी जारी रह सकता है। यह उसी तरह काम करता है जैसे कि JUnit 5assertThrows
। यह एक मौजूदा सुरक्षा प्रबंधक का भी सम्मान करता है।
एक शेष समस्या है: जब परीक्षण के तहत कोड एक नया सुरक्षा प्रबंधक स्थापित करता है जो परीक्षण द्वारा निर्धारित सुरक्षा प्रबंधक को पूरी तरह से बदल देता है। SecurityManager
मेरे लिए ज्ञात अन्य सभी- आधारित समाधान एक ही समस्या से ग्रस्त हैं।
import java.security.Permission;
import static java.lang.System.getSecurityManager;
import static java.lang.System.setSecurityManager;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public enum ExitAssertions {
;
public static <E extends Throwable> void assertExits(final int expectedStatus, final ThrowingExecutable<E> executable) throws E {
final SecurityManager originalSecurityManager = getSecurityManager();
setSecurityManager(new SecurityManager() {
@Override
public void checkPermission(final Permission perm) {
if (originalSecurityManager != null)
originalSecurityManager.checkPermission(perm);
}
@Override
public void checkPermission(final Permission perm, final Object context) {
if (originalSecurityManager != null)
originalSecurityManager.checkPermission(perm, context);
}
@Override
public void checkExit(final int status) {
super.checkExit(status);
throw new ExitException(status);
}
});
try {
executable.run();
fail("Expected System.exit(" + expectedStatus + ") to be called, but it wasn't called.");
} catch (final ExitException e) {
assertEquals(expectedStatus, e.status, "Wrong System.exit() status.");
} finally {
setSecurityManager(originalSecurityManager);
}
}
public interface ThrowingExecutable<E extends Throwable> {
void run() throws E;
}
private static class ExitException extends SecurityException {
final int status;
private ExitException(final int status) {
this.status = status;
}
}
}
आप इस तरह वर्ग का उपयोग कर सकते हैं:
@Test
void example() {
assertExits(0, () -> System.exit(0)); // succeeds
assertExits(1, () -> System.exit(1)); // succeeds
assertExits(2, () -> System.exit(1)); // fails
}
यदि आवश्यक हो तो कोड को आसानी से JUnit 4, TestNG, या किसी अन्य ढांचे में पोर्ट किया जा सकता है। एकमात्र फ्रेमवर्क-विशिष्ट तत्व परीक्षण में विफल हो रहा है। इसे आसानी से कुछ फ्रेमवर्क-इंडिपेंडेंट (एक जून 4 के अलावा) में बदला जा सकता है Rule
सुधार के लिए जगह है, उदाहरण के लिए, assertExits()
अनुकूलन संदेशों के साथ ओवरलोडिंग ।