2011-07-16 15 views
26

मेरे पास जुनीट में कई परीक्षण मामले हैं। उन सभी को उनके @BeforeClass स्थैतिक विधि में निष्पादित करने के लिए एक ही कोड की आवश्यकता है। यह एक कोड डुप्लिकेशन है और मैं इसे से छुटकारा पाने की कोशिश कर रहा हूं। ऐसा करने का एक गंदा तरीका विरासत से है। क्या जुनीट में कोई अन्य तंत्र है, जो मदद कर सकता है?जुनीट परीक्षण मामलों में विरासत से कैसे बचें?

पी एस। मैंने इस ब्लॉग पोस्ट को इस विषय के बारे में लिखा: http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html

+0

क्या सभी '@ पहले क्लास' बिल्कुल समान हैं या क्या वे कुछ कोड साझा करते हैं? –

+1

विरासत एक गंदे तरीके क्यों है? –

+0

@lu, विधि स्थैतिक है, और विरासत सबसे अच्छी बात नहीं होगी। –

उत्तर

26

पुन: प्रयोज्य कोड लिखने के लिए जुनीट तरीका (इसके द्वारा विरासत के बजाय) नियम हैं।

देखें https://github.com/junit-team/junit/wiki/Rules

यहाँ एक गूंगा नमूना है, लेकिन आप बिंदु मिल जाएगा।

import org.junit.rules.TestRule; 
import org.junit.runners.model.Statement; 
import org.junit.runner.Description; 

public class MyTestRule implements TestRule { 
    @Override 
    public Statement apply(final Statement statement, Description description) { 
    return new Statement() { 
     public void evaluate() throws Throwable { 
     // Here is BEFORE_CODE 
     try { 
      statement.evaluate(); 
     } finally { 
      // Here is AFTER_CODE 
     } 
     } 
    }; 
    } 
} 

फिर आप इस तरह अपने TestRule उपयोग कर सकते हैं:

import org.junit.Rule; 

public class MyTest { 
    @Rule 
    public MyTestRule myRule = new MyTestRule(); 
} 

BEFORE_CODE और AFTER_CODE तो अपने परीक्षण तरीकों में से प्रत्येक के आसपास निष्पादित किया जाएगा।

आप कक्षा प्रति केवल एक बार अपने कोड को चलाने के लिए एक @ClassRule के रूप में अपने TestRule का उपयोग की जरूरत है:

import org.junit.ClassRule; 

public class MyTest { 
    @ClassRule 
    public static MyTestRule myRule = new MyTestRule(); 
} 

अब, BEFORE_CODE और AFTER_CODE अपने परीक्षण के वर्ग की प्रत्येक चारों ओर निष्पादित किया जाएगा।

@Rule फ़ील्ड स्थिर नहीं है, @ClassRule फ़ील्ड है।

ए @ क्लासरूले को सूट में भी घोषित किया जा सकता है।

ध्यान दें कि आप एक एकल परीक्षा कक्षा में कई नियम घोषित कर सकते हैं, इस प्रकार आप टेस्ट-सूट, टेस्ट-क्लासेस और टेस्ट-विधियों के स्तर पर परीक्षण जीवन चक्र लिखते हैं।

एक नियम एक वस्तु है जिसे आप अपने परीक्षण वर्गों (स्थिर या नहीं) में instanciate है। यदि आवश्यक हो तो आप नियंत्रक पैरामीटर जोड़ सकते हैं।

एचटीएच

4

यदि विधि किसी प्रकार की उपयोगिता है, तो इसे एक स्थिर विधि के साथ अलग वर्ग में अलग करें और उस विधि को अपने @BeforeClass में कॉल करें।

मैं इस तथ्य पर जोर देता हूं कि विरासत का उपयोग न करें क्योंकि यह आपकी समस्या का समाधान करता है, ऐसा करने पर इसका उपयोग करें, जिससे आपकी कक्षा पदानुक्रम में समझ आती है।

0

प्रत्येक और हर वर्ग एक @BeforeClass एनोटेट विधि है बिल्कुल हर दूसरे के रूप में ही की जरूरत है, तो विरासत कि मेरे लिए गलत महसूस नहीं करता है। यदि इनमें से प्रत्येक प्रारंभिक विधियां कुछ कोड साझा करती हैं, तो आप कुछ साझा व्यवहार के साथ TestUtil कक्षा बना सकते हैं और @BeforeClass विधियों में से प्रत्येक साझा साझा व्यवहार को कॉल कर सकते हैं।

1

स्टेटिक विधियां विरासत में नहीं हैं, इसलिए विरासत डिफ़ॉल्ट रूप से एक विकल्प नहीं है। यदि आपका मतलब है कि आप विधि को एक सामान्य अभिभावक वर्ग में ले जा रहे हैं, तो यह एक खराब विकल्प लगता है क्योंकि आप केवल जावा में एक माता-पिता प्राप्त करते हैं। किसी प्रकार का परीक्षण समर्थन वर्ग अधिक उपयुक्त प्रतीत होता है। यह भी संभव है कि आपको parameterized test की आवश्यकता दिखाई दे रही है।

0

मुझे लगता है कि कक्षाओं में "is-a" संबंध है, विरासत उचित है।

आधार वर्ग MyBeforeClass है जो परिभाषित करता है @BeforeClass विधि, और MyTestClass1 "है-एक" MyBeforeClass, MyTestClass1 extends MyBeforeClass ठीक है।

0

सेटअप कोड की प्रकृति के आधार पर, आप संभावित रूप से अपने सभी परीक्षणों को एक परीक्षण suite में डाल सकते हैं और सेटअप कोड चला सकते हैं। इसका नकारात्मक पक्ष यह है कि आप व्यक्तिगत रूप से परीक्षण नहीं चला सकते हैं (क्योंकि परीक्षण सेटअप कोड पर निर्भर करता है)।

1

इस मामले में विरासत के साथ बिल्कुल कुछ भी गलत नहीं है, यह वास्तव में प्रत्येक उपclass में इस कोड को दोहराने से बचने का एकमात्र तरीका है। तथ्य यह है कि @BeforeClass विधियों को ज्युनिट में स्थैतिक घोषित किया जाना दुर्भाग्यपूर्ण है, लेकिन इससे आपको रोकना नहीं चाहिए। कक्षा बढ़ाएं और आपके पास प्रारंभिक कोड स्वचालित रूप से कुछ भी किए बिना आपके लिए चलाया गया है।

+0

नहीं, यह एकमात्र तरीका नहीं है, अन्य उत्तरों देखें, और स्थिर विधियों को विरासत में नहीं मिला है, यह संदिग्ध है कि यह एक तरीका है या नहीं। या तुमने कोशिश की? – EJP

2

आप परीक्षण धावक

public class MyTestRunner extends BlockJUnit4ClassRunner { 
    @Override 
    protected Object createTest() throws Exception { 
    Object test = super.createTest(); 
    doStuff(); 
    } 

    public void doStuff(){ 
    //common code 
    } 
} 


@RunWith(MyTestRunner.class) 
public class MyTest1{ 
    @Test 
    public void test1(){ 
     //test method 
    } 
} 
-2

यह परीक्षण कोड है, और यह भारी फिर से उपयोग के लिए नहीं होती बना सकते हैं। अधिक इंजीनियर नहीं है। आप जानते हैं कि सभी डिजाइन पैटर्न लागू न करें। परीक्षण कोड के लिए, नियम अलग हैं।

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