2012-02-03 11 views
13

एक यूनिट परीक्षण में, मुझे एक जटिल जटिल सेटअप करने की आवश्यकता है (यह एक कोड गंध हो सकता है लेकिन यह सवाल इस बारे में नहीं है :-)) । मुझे क्या दिलचस्पी है यह है कि सेटअप करने के लिए एकाधिक @Before विधियां बेहतर हैं या केवल एक, जो प्रारंभ करने के लिए सहायक विधियों को कॉल करता है।जुनीट - एकाधिक @ पहले बनाम एक @ इससे पहले विधियों में विभाजित

उदा।

@Before 
public void setUpClientStub() { 

} 

@Before 
public void setUpObjectUnderTest() { 

} 

बनाम

@Before 
public void setUp() { 
    setUpClientStub(); 
    setUpObjectUnderTest(); 
} 
+1

क्या एक baseclass के बारे में:

public static class UsesExternalResource { private TestRule clientRule = new ExternalResource() { @Override protected void before() throws Throwable { setupClientCode(); }; @Override protected void after() { tearDownClientCode() }; }; @Rule public TestRule chain = RuleChain .outerRule(clientRule) .around(objectRule); } 

तो आप निम्नलिखित निष्पादन आदेश होगा? अन्यथा मैं विधियों के खिलाफ कोई बिंदु नहीं देखता ... – wuppi

उत्तर

20

जैसा कि अन्य प्रतिक्रियाओं में कहा गया है, जिस क्रम में जुनीट को विधि मिलती है, उसकी गारंटी नहीं है, इसलिए @Before विधियों के निष्पादन आदेश की गारंटी नहीं दी जा सकती है। @Rule के बारे में भी यही सच है, यह गारंटी की समान कमी से पीड़ित है। यदि यह हमेशा एक ही कोड होगा, तो दो विधियों में विभाजित करने में कोई बात नहीं है।

यदि आपके पास दो विधियां हैं, और अधिक महत्वपूर्ण बात यह है कि, यदि आप उन्हें कई स्थानों से उपयोग करना चाहते हैं, तो आप RuleChain का उपयोग करके नियमों को जोड़ सकते हैं, जिसे 4.10 में पेश किया गया था।

public static class UseRuleChain { 
    @Rule 
    public TestRule chain= RuleChain 
       .outerRule(new LoggingRule("outer rule")) 
       .around(new LoggingRule("middle rule")) 
       .around(new LoggingRule("inner rule")); 

    @Test 
    public void example() { 
     assertTrue(true); 
    } 
} 

यह पैदा करता है:

starting outer rule 
starting middle rule 
starting inner rule 
finished inner rule 
finished middle rule 
finished outer rule 

तो आप या तो 4.10 में नवीनीकृत कर सकते हैं या सिर्फ वर्ग चोरी इस तरह के रूप में नियमों, के विशिष्ट आदेश देने की अनुमति देता है।

अपने मामले में, आप दो नियमों को परिभाषित कर सकते हैं, एक ग्राहक सेटअप के लिए और एक ऑब्जेक्ट के लिए, और RuleChain में उन्हें गठबंधन कर सकते हैं। ExternalResource का उपयोग करना।

clientRule.before() 
objectRule.before() 
the test 
objectRule.after() 
clientRule.after() 
+0

यह एक अच्छा समाधान है, लेकिन पठनीयता के मामले में मैंने @ hvgotcodes सुझाव चुना होगा। – Timo

+1

भले ही विधियों का पुन: उपयोग नहीं किया जा रहा हो, फिर भी विधि में टिप्पणियां जोड़ने के विपरीत, उन्हें सार्थक नाम देने के लिए उन्हें अलग-अलग तरीकों के रूप में समझने का अर्थ हो सकता है। – herman

5

मैं बाद करना होगा। AFAIK, एनोटेटेड सेटअप विधियों से पहले @ आदेश की गारंटी देने का कोई तरीका नहीं है।

2

मुझे नहीं लगता कि इससे कोई फर्क पड़ता है, लेकिन मैं व्यक्तिगत रूप से दूसरा विकल्प पसंद करता हूं (ऑर्डर से पहले विधियों को परिभाषित नहीं किया जा रहा है, आपके पास इस तरह बेहतर नियंत्रण होगा)।

3

ध्यान दें कि आदेश के बारे में कोई गारंटी नहीं है जिसमें @Before एनोटेटेड विधियां लागू की गई हैं। यदि उनके बीच कुछ निर्भरताएं हैं (उदाहरण के लिए एक विधि को दूसरे से पहले बुलाया जाना चाहिए), तो आप बाद वाले फॉर्म का उपयोग कर सकते हैं।

अन्यथा यह वरीयता का मामला है, बस उन्हें एक ही स्थान पर रखें ताकि उन्हें खोजना आसान हो।

संबंधित मुद्दे