Moq

2009-04-07 12 views
18

के साथ संदर्भ पैरामीटर का मान सत्यापित करें मैंने अभी Moq पर स्विच किया है और एक समस्या में भाग लिया है। मैं एक ऐसी विधि का परीक्षण कर रहा हूं जो किसी व्यवसाय ऑब्जेक्ट का एक नया उदाहरण बनाता है, ऑब्जेक्ट के गुणों को उपयोगकर्ता इनपुट मानों से सेट करता है और नई ऑब्जेक्ट को सहेजने के लिए एक विधि (SaveCustomerContact) को कॉल करता है। व्यापार वस्तु को रेफ तर्क के रूप में पारित किया जाता है क्योंकि यह एक रिमोटिंग परत के माध्यम से जाता है। मुझे यह जांचने की ज़रूरत है कि SaveCustomerContact को पारित ऑब्जेक्ट को इसकी सभी गुणों को अपेक्षित के रूप में सेट किया गया है, लेकिन क्योंकि यह नियंत्रक विधि में नए के रूप में तत्काल है, इसलिए ऐसा नहीं लगता है।Moq

[TestMethod()] 
public void AddContactTest() { 

    int customerId = 0; 

    string name = "a"; 

    var actual = new CustomerContact(); 

    var expected = new CustomerContact() { 
     CustomerId = customerId, 
     Name = name 
    }; 

    model.Setup(m => m.CustomerId).Returns(customerId); 
    model.SetupProperty(m => model.CustomerContactName, name); 
    model.SetupProperty(m => m.PhoneNumber, string.Empty); 
    model.SetupProperty(m => m.FaxNumber, string.Empty); 
    model.SetupProperty(m => m.Email, string.Empty); 
    model.SetupProperty(m => m.ReceiveInvoiceFlag, false); 
    model.SetupProperty(m => m.ReceiveStatementFlag, false); 
    model.SetupProperty(m => m.ReceiveContractFlag, false); 
    model.SetupProperty(m => m.EmailFlag, false); 
    model.SetupProperty(m => m.FaxFlag, false); 
    model.SetupProperty(m => m.PostalMailFlag, false); 
    model.SetupProperty(m => m.CustomerLocationId, 0); 

    remote 
     .Setup(r => r.SaveCustomerContact(ref actual)) 
     .Callback(() => Assert.AreEqual(actual, expected)); 

    target.AddContact(); 

} 

यह सिर्फ सबसे उस पैरामीटर के ahold पाने के कई प्रयासों की हाल ही में है:

public void AddContact() { 

    var contact = new CustomerContact() { CustomerId = m_model.CustomerId }; 

    contact.Name = m_model.CustomerContactName; 
    contact.PhoneNumber = m_model.PhoneNumber; 
    contact.FaxNumber = m_model.FaxNumber; 
    contact.Email = m_model.Email; 
    contact.ReceiveInvoiceFlag = m_model.ReceiveInvoiceFlag; 
    contact.ReceiveStatementFlag = m_model.ReceiveStatementFlag; 
    contact.ReceiveContractFlag = m_model.ReceiveContractFlag; 
    contact.EmailFlag = m_model.EmailFlag; 
    contact.FaxFlag = m_model.FaxFlag; 
    contact.PostalMailFlag = m_model.PostalMailFlag; 
    contact.CustomerLocationId = m_model.CustomerLocationId; 

    RemotingHandler.SaveCustomerContact(ref contact); 
} 

यहाँ परीक्षण है। संदर्भ के लिए, वास्तविक का मूल्य प्रारंभिक (निर्मित) राज्य से नहीं बदला जाता है।

दावा को स्थानांतरित करना। लक्ष्य कॉल विफल होने के बाद AREEqual (अपेक्षित, वास्तविक) विफल रहता है। यदि मैं जोड़ता हूं। वर्कबैक() को .allBack के बजाय सेटअप में जोड़ें और फिर रिमोट कॉल करें। लक्ष्य के बाद सत्यापित करें (या, मुझे लगता है कि, सख्त करने के लिए नकली सेट करें) यह हमेशा विफल रहता है क्योंकि परीक्षण में प्रदान किया गया पैरामीटर नहीं है एक ही उदाहरण के रूप में नियंत्रक विधि में बनाया गया है।

मैं Moq 3.0.308.2 का उपयोग कर रहा हूं। इसका परीक्षण करने के तरीके पर किसी भी विचार की सराहना की जाएगी। धन्यवाद!

उत्तर

19

मैं आपको एक सटीक समाधान नहीं दे सकता, लेकिन एक विकल्प एडाप्टर के पीछे पास-बाय-रेफ सेमेन्टिक्स को छिपाना होगा, जो पैरामीटर को मूल्य से ले जाता है और इसे रिमोटिंग हैंडलर को आगे बढ़ाता है।यह उपहास करने के लिए आसान होगा, और इंटरफ़ेस की "रेफरी" मस्सा हटाने (मैं हमेशा रेफरी पैरामीटर :-) पर शक कर रहा हूँ)

संपादित करें:

या आप एक नकली के बजाय एक ठूंठ इस्तेमाल कर सकते हैं उदाहरण के लिए:

public class StubRemotingHandler : IRemotingHandler 
{ 
    public CustomerContact savedContact; 

    public void SaveCustomerContact(ref CustomerContact contact) 
    { 
     savedContact = contact; 
    } 
} 

अब आप को बचाया वस्तु अपने परीक्षण में जांच कर सकते हैं:

IRemotingHandler remote = new StubRemotingHandler(); 
... 
//pass the stub to your object-under-test 
... 
target.AddContact(); 
Assert.AreEqual(expected, remote.savedContact); 

आप भी अपनी टिप्पणी में कहते हैं:

मैं तो मैं परीक्षण और अधिक आसानी से लिख सकते हैं बैकएंड के यादृच्छिक बिट्स लपेटकर की एक मिसाल शुरू करने के लिए नफरत करता हूँ

मुझे लगता है कि वास्तव में मिसाल आप निर्धारित करने की आवश्यकता है! यदि आपका कोड टेस्टेबल नहीं है, तो आप इसका परीक्षण करने के लिए संघर्ष कर रहे हैं। परीक्षण करना आसान बनाएं, और अपना कवरेज बढ़ाएं।

+0

मुझे लगता है कि मुझे यकीन नहीं है कि आप इसे कैसे दबाएंगे (हालांकि मुझे स्टब्स के बारे में ज्यादा जानकारी नहीं है)। क्या आप विस्तारित कर सकते हैं कि इसे कैसे संभाला जा सकता है? –

+0

इसके अलावा, जितना मैं आपके साथ रेफरी मुद्दे पर सहमत हूं, वैसे ही हमारी रिमोटिंग परत काम करती है और मैं बैकएंड के यादृच्छिक बिट्स को लपेटने का एक उदाहरण शुरू करने से नफरत करता हूं ताकि मैं परीक्षण आसानी से लिख सकूं। –

+0

मुझे एक समान समस्या थी, और एमओक्यू काम करने में इतनी शून्य हो गई, मैं भूल गया कि मैं अपना खुद का स्टब लिख सकता हूं! धन्यवाद। –

9

दुर्भाग्य से, मुझे यकीन नहीं है कि यह मोक से सीधे समर्थन के बिना संभव है। समस्या यह है कि लैम्ब्डा अभिव्यक्ति रेफरी या आउट का समर्थन नहीं करती है।

"एक लैम्ब्डा अभिव्यक्ति सीधे एक संलग्न विधि से एक रेफरी या बाहर पैरामीटर पर कब्जा नहीं कर सकते।"

http://msdn.microsoft.com/en-us/library/bb397687.aspx

मैं आपके जैसे काम करने के लिए भी नहीं एक उदाहरण हो सकता है। सेटअप में रेफरी जोड़ना संकलित करने में विफल रहता है।

आप अधिक http://groups.google.com/group/moqdisc

गुड लक के लिए Moq विचार विमर्श की जाँच कर सकते हैं।

+0

महान जवाब! :) – Delashmate

10

Moq का नवीनतम संस्करण इस परिदृश्य का समर्थन करता है।

http://code.google.com/p/moq/wiki/QuickStart पर त्वरित प्रारंभ से लिया:

// ref arguments 
var instance = new Bar(); 
// Only matches if the ref argument to the invocation is the same instance 
mock.Setup(foo => foo.Submit(ref instance)).Returns(true); 
+6

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

0

मैं वही समस्या का सामना करना पड़ा। बिट मुझे नवीनतम Moq का उपयोग करके समाधान मिला और

var instance = new bar(); मॉक.Setup (foo => foo.Submit (ref instance))। रिटर्न (सत्य);

इससे पहले भी, मैं एक ही विधि का उपयोग कर रहा था, लेकिन मुझे सच के रूप में वापस नहीं मिल रहा था।

वास्तविक फ़ंक्शन इंस्टेंस के अंदर यूनिट टेस्ट क्लास से पारित उदाहरण को ओवरराइट करना और ओवरराइट करना समस्या उत्पन्न कर रहा था। मैंने वास्तविक वर्ग के अंदर उदाहरण निर्माण को हटा दिया और फिर यह काम किया।

आशा है कि यह आपकी मदद करेगा।

धन्यवाद