2011-03-10 8 views
26

में बिना तर्क-तर्क कन्स्ट्रक्टर के ऑब्जेक्ट्स मॉकिंग करना क्या कक्षा से एक नकली बनाना संभव है जो नो-तर्क कन्स्ट्रक्टर प्रदान नहीं करता है और कन्स्ट्रक्टर को कोई तर्क नहीं देता है? शायद आईएल गतिशील बनाने के साथ?सी #/.NET

पृष्ठभूमि यह है कि मैं केवल परीक्षण के लिए इंटरफेस को परिभाषित नहीं करना चाहता हूं। कामकाज परीक्षण के लिए एक गैर-तर्क कन्स्ट्रक्टर प्रदान करना होगा।

+3

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

+0

मोक्स बनाने के लिए एक मोक उपयोग से भी बात करते हुए, आपको विधियों को आभासी बनाने की आवश्यकता होगी। ऐसा लगता है कि उस मामले में एक इंटरफेस आम तौर पर बेहतर होता है। अन्य मॉकिंग ढांचे के बारे में निश्चित नहीं है। –

+3

आदर्श रूप से इंटरफेस का उपयोग आपके कोड में किया जाना चाहिए; कंक्रीट कार्यान्वयन के विरुद्ध, इस प्रकार "एक परीक्षण बिंदु के लिए केवल इंटरफेस बनाने" की टिप्पणी कर रहा है। –

उत्तर

38

ज़रूर बात। इस उदाहरण में मैं मोक का उपयोग करूंगा, वास्तव में एक शानदार मजाकिया पुस्तकालय।

उदाहरण:

public class MyObject 
{ 
    public MyObject(object A, object B, object C) 
    { 
      // Assign your dependencies to whatever 
    } 
} 

Mock<MyObject> mockObject = new Mock<MyObject>(); 
Mock<MyObject> mockObject = new Mock<MyObject>(null, null, null); // Pass Nulls to specific constructor arguments, or 0 if int, etc 

कई मामलों में, हालांकि, मैं तर्क के रूप में नकली वस्तुओं आवंटित तो मैं निर्भरता का परीक्षण कर सकते हैं:

Mock<Something> x = new Mock<Something>(); 
MyObject mockObject = new MyObject(x.Object); 

x.Setup(d => d.DoSomething()).Returns(new SomethingElse()); 

etc 
+0

सहमत हो सकता है। Moq भयानक है। उनके पास एक वेब पेज पर एक पूर्ण संदर्भ कैसे है। आप आसानी से उपयोग/सीखने के लिए नहीं हो सकते हैं। –

+2

क्या यह काम करता है जब निर्माता को शून्य मानों की आवश्यकता होती है (कोड अनुबंध या अपवाद के साथ)? – deamon

+0

उदाहरण के लिए, यदि आपके पास एक पूर्णांक है, तो आप 0 को पास कर सकते हैं। यदि यह एक स्ट्रिंग है, नल, स्ट्रिंग। लक्षण, आदि। आप डिफ़ॉल्ट रूप से बहुत अधिक (टी) के साथ जा सकते हैं, जहां टी: आपका पैरामीटर प्रकार और सब कुछ काम करता है ठीक। यदि आप नकली वस्तु बना रहे हैं, वर्चुअल के रूप में चिह्नित विधियों/गुणों को कभी निष्पादित नहीं किया जाएगा; आप नकली ऑब्जेक्ट पर जो भी करते हैं (कॉलबैक के माध्यम से) या वे क्या लौटते हैं (रिटर्न विधि के माध्यम से) नियंत्रित कर सकते हैं। – Tejs

1

यह मानना ​​गलत है कि आप केवल परीक्षण के लिए इंटरफेस प्रदान कर रहे हैं। इंटरफेस अबास्ट्रक्शन प्रदान करने के लिए हैं और आपके कोड की विभिन्न परतों के बीच युग्मन को कमजोर करते हैं जिससे उन्हें विभिन्न संदर्भों में अधिक पुन: प्रयोज्य बना दिया जाता है।

यह कहा जा रहा है कि उत्तर आपके द्वारा उपयोग किए जा रहे मॉकिंग फ्रेमवर्क पर निर्भर करेगा। राइनो Mocks साथ उदाहरण के लिए आप हो सकता है:

public class Foo 
{ 
    public Foo(string bar) 
    { } 

    public virtual int SomeMethod() 
    { 
     return 5; 
    } 
} 

और उसके बाद:

var fooMock = MockRepository.GeneratePartialMock<Foo>("abc"); 
fooMock.Expect(x => x.SomeMethod()).Return(10); 
+1

आपके दृष्टिकोण पर निर्भर करता है: सच है, एक डेवलपर को युग्मन कमजोर करने के लिए इंटरफेस लिखना चाहिए। झूठा, एक क्यूए परीक्षण उद्देश्यों के लिए केवल कार्यात्मक कोड "सुधार" नहीं करना चाहता है अगर वह – PPC