प्रथम अंक के लिए एक समाधान एक @ClassRule
, JUnit 4.9 में शुरू की के माध्यम से org.junit.rules.ExternalResource
परीक्षण को झुका का ही विस्तार में तर्क स्थानांतरित करने के लिए है:
public class MyTest {
@ClassRule
public static final TestResources res = new TestResources();
@Test
public void testFoo() {
// test logic here
}
}
public class TestResources extends ExternalResource {
protected void before() {
// Setup logic that used to be in @BeforeClass
}
protected void after() {
// Setup logic that used to be in @AfterClass
}
}
इस तरह, संसाधनों पहले बेस क्लास द्वारा प्रबंधित किया जाता है, टेस्ट क्लास पदानुक्रम से बाहर और अधिक मॉड्यूलर/उपभोग्य "संसाधन" में स्थानांतरित किया जाता है जिसे क्लास रन के बाद कक्षा चलाने और नष्ट करने से पहले बनाया जा सकता है।
एक ही समय में दोनों मुद्दों को हल करने के लिए - यानी: एक ही उच्च स्तर के सेटअप/टियरडाउन को एक व्यक्तिगत परीक्षण के हिस्से के रूप में चलाने और सूट के हिस्से के रूप में चलाने के लिए - कोई विशिष्ट निर्मित नहीं लगता है इसके लिए समर्थन में। हालांकि ..., आप इसे खुद को लागू कर सकते हैं:
बस एक कारखाना पैटर्न है कि संदर्भ आंतरिक रूप से गिनती निर्धारित करने के लिए किया जाए या नहीं/बनाने के लिए संसाधन को नष्ट करता है में @ClassRule
संसाधन सृजन बदल जाते हैं।
उदाहरण के लिए (कृपया ध्यान दें यह किसी न किसी तरह है और मजबूती के लिए से निपटने के कुछ तोड़ मरोड़/त्रुटि आवश्यकता हो सकती है):
public class TestResources extends ExternalResource {
private static int refCount = 0;
private static TestResources currentInstance;
public static TestResources getTestResources() {
if (refCount == 0) {
// currentInstance either hasn't been created yet, or after was called on it - create a new one
currentInstance = new TestResources();
}
return currentInstance;
}
private TestResources() {
System.out.println("TestResources construction");
// setup any instance vars
}
protected void before() {
System.out.println("TestResources before");
try {
if (refCount == 0) {
System.out.println("Do actual TestResources init");
}
}
finally {
refCount++;
}
}
protected void after() {
System.out.println("TestResources after");
refCount--;
if (refCount == 0) {
System.out.println("Do actual TestResources destroy");
}
}
}
दोनों अपने सूट/परीक्षण कक्षाएं सिर्फ कारखाने विधि के माध्यम से एक @ClassResource
के रूप में संसाधन का प्रयोग करेंगे:
@RunWith(Suite.class)
@SuiteClasses({FooTest.class, BarTest.class})
public class MySuite {
@ClassRule
public static TestResources res = TestResources.getTestResources();
@BeforeClass
public static void suiteSetup() {
System.out.println("Suite setup");
}
@AfterClass
public static void suiteTeardown() {
System.out.println("Suite teardown");
}
}
public class FooTest {
@ClassRule
public static TestResources res = TestResources.getTestResources();
@Test
public void testFoo() {
System.out.println("testFoo");
}
}
public class BarTest {
@ClassRule
public static TestResources res = TestResources.getTestResources();
@Test
public void testBar() {
System.out.println("testBar");
}
}
जब एक व्यक्ति परीक्षण चलाने के refcounting कोई असर नहीं होगा - "वास्तविक init" और "वास्तविक टियरडाउन" केवल एक बार नहीं होगा। सूट के माध्यम से चलते समय, सूट टेस्ट रिसोर्स बनायेगा, और व्यक्तिगत परीक्षण पहले से ही तत्काल तत्काल पुन: उपयोग करेंगे (refcounting इसे वास्तव में नष्ट होने और सूट में परीक्षणों के बीच पुनर्निर्मित होने से रोकता है)।
मुझे लगता है कि आपकी रेफकाउंट सिस्टम काम नहीं करती है। यह प्रत्येक वर्ग के बाद शून्य हो जाएगा और आपके संसाधन को हटा देगा और फिर getTestResources() को कॉल करते समय इसे अगले वर्ग पर पुन: प्रारंभ करें। मुझे कुछ याद आ रहा है, अगर मैं गलत हूं तो मुझे सही करें। – FredBoutin
विचार यह है कि यह एक व्यक्तिगत परीक्षण या परीक्षण के एक सूट चलाने के दौरान शुरू कर सकते हैं। ** सूट ** के रूप में चलते समय, रीफकाउंट सूट 'क्लासरुले' द्वारा 1 पर सेट किया जाता है। प्रत्येक परीक्षण refCount 2 को बदल देगा, फिर इसे पूरा होने पर 1 तक वापस कर देगा। जब सुइट किया जाता है, तो यह 0 पर जाएगा। ** ** परीक्षण के रूप में चलते समय, रेफकाउंट व्यक्तिगत परीक्षण द्वारा 1 पर सेट किया जाता है, फिर परीक्षण पूरा होने पर 0 तक। मुद्दा यह है कि संसाधन केवल चलाने के दोनों तरीकों में एक बार बनाया और नष्ट हो जाता है। – Krease
बहुत स्पष्ट धन्यवाद @ क्रेज़! – FredBoutin