2012-06-30 8 views
16

मेरे पास कुछ मौके हैं जहां ऐसा कुछ उपयोगी होगा। उदाहरण के लिए, Create विधि के साथ है जो NewAccount लेता है। मेरा AccountCreator में IRepository है जिसका अंततः खाता बनाने के लिए उपयोग किया जाएगा। मेरा AccountCreator पहले गुणों को NewAccount से Account पर मानचित्र करेगा, दूसरा इसे Account को रेपो में अंत में बनाने के लिए पास करेगा। ,यह सत्यापित करने के लिए moq का उपयोग कैसे करें कि एक समान ऑब्जेक्ट को तर्क के रूप में पारित किया गया था?

public class when_creating_an_account 
{ 
    static Mock<IRepository> _mockedRepository; 
    static AccountCreator _accountCreator; 
    static NewAccount _newAccount; 
    static Account _result; 
    static Account _account; 

    Establish context =() => 
     { 
      _mockedRepository = new Mock<IRepository>(); 
      _accountCreator = new AccountCreator(_mockedRepository.Object); 

      _newAccount = new NewAccount(); 
      _account = new Account(); 

      _mockedRepository 
       .Setup(x => x.Create(Moq.It.IsAny<Account>())) 
       .Returns(_account); 
     }; 

    Because of =() => _result = _accountCreator.Create(_newAccount); 

    It should_create_the_account_in_the_repository =() => _result.ShouldEqual(_account); 
} 

तो, मैं क्या जरूरत है कुछ It.IsAny<Account> को बदलने के लिए है, क्योंकि है कि मुझे तो सत्यापित करें कि सही खाता बनाया गया था मदद नहीं करता है: मेरा परीक्षण कुछ इस तरह दिखाई। क्या अद्भुत होगा कुछ की तरह है ...

public class when_creating_an_account 
{ 
    static Mock<IRepository> _mockedRepository; 
    static AccountCreator _accountCreator; 
    static NewAccount _newAccount; 
    static Account _result; 
    static Account _account; 

    Establish context =() => 
     { 
      _mockedRepository = new Mock<IRepository>(); 
      _accountCreator = new AccountCreator(_mockedRepository.Object); 

      _newAccount = new NewAccount 
       { 
        //full of populated properties 
       }; 
      _account = new Account 
       { 
        //matching properties to verify correct mapping 
       }; 

      _mockedRepository 
       .Setup(x => x.Create(Moq.It.IsLike<Account>(_account))) 
       .Returns(_account); 
     }; 

    Because of =() => _result = _accountCreator.Create(_newAccount); 

    It should_create_the_account_in_the_repository =() => _result.ShouldEqual(_account); 
} 

सूचना मैं It.IsLike<> को It.IsAny<> बदल गया है और एक आबादी वाले Account वस्तु में पारित कर दिया। आदर्श रूप से, पृष्ठभूमि में, कुछ संपत्ति मूल्यों की तुलना करेगा और अगर वे सभी मेल खाते हैं तो इसे पारित कर दें।

तो, क्या यह पहले से मौजूद है? या हो सकता है कि यह कुछ ऐसा हो जो आपने पहले किया है और कोड साझा करने में कोई दिक्कत नहीं होगी?

+1

Moq कस्टम matchers का समर्थन करता है - के रूप में, आप जब एक कॉल के लिए बहस मिलान इस्तेमाल किया कस्टम comparers हो सकता है , लेकिन आपको इसे स्वयं लागू करना होगा। उदाहरण देखें [यहां] (http://stackoverflow.com/a/10300051/343266)। –

उत्तर

20

भंडार बाहर ठूंठ की तरह मानदंडों के आधार पर एक विशेष मान देने के लिए, निम्न कार्य करना चाहिए:

_repositoryStub 
    .Setup(x => x.Create(
     Moq.It.Is<Account>(a => _maskAccount.ToExpectedObject().Equals(a)))) 
    .Returns(_account); 
+0

अब, यह वही है जो मैं ढूंढ रहा था! धन्यवाद डेरेक! –

+3

यदि कोई इस जवाब में ठोकर खा रहा है और वही बात करना चाहता है, तो आपको ExpectedObjects लाइब्रेरी को शामिल करना होगा। https://github.com/derekgreer/expectedObjects या 'इंस्टॉल-पैकेज अपेक्षित ऑब्जेक्ट्स' –

12

आप के लिए काम करना चाहिए निम्नलिखित:

Moq.It.Is<Account>(a=>a.Property1 == _account.Property1) 

हालांकि के रूप में यह उल्लेख किया गया था आप मिलान मापदंड लागू करने के लिए की है।

+0

मैं हर दिन इसका उपयोग करता हूं। लेकिन कल्पना करें कि "ए" 50 गुणों वाला एक वर्ग है। मैं वास्तविक ऑब्जेक्ट (इसकी सभी गुणों के साथ) की अपेक्षाकृत ऑब्जेक्ट (इसकी सभी अपेक्षित गुणों के साथ) की तुलना करने के लिए अपेक्षित ऑब्जेक्ट पैटर्न का उपयोग करने में सक्षम होना चाहूंगा। यही वह है जिसे मैं बाहर रख रहा हूं। –

0

मैं कुछ भी नहीं ढूंढ पाया जो वास्तव में प्रश्न में वर्णित है। इस बीच, मैक किए गए तरीकों (रेफरेंसियल समानता के विलासिता के बिना) के तर्कों के रूप में पारित वस्तुओं के सत्यापन को संभालने का सबसे अच्छा तरीका Callback का संयोजन है और अनुमानित ऑब्जेक्ट पैटर्न अपेक्षित ऑब्जेक्ट के साथ वास्तविक की तुलना करने के लिए है:

public class when_creating_an_account 
{ 
    static Mock<IRepository> _mockedRepository; 
    static AccountCreator _accountCreator; 
    static NewAccount _newAccount; 
    static Account _result; 
    static Account _expectedAccount; 
    static Account _actualAccount; 

    Establish context =() => 
     { 
      _mockedRepository = new Mock<IRepository>(); 
      _accountCreator = new AccountCreator(_mockedRepository.Object); 

      _newAccount = new NewAccount 
       { 
        //full of populated properties 
       }; 
      _expectedAccount = new Account 
       { 
        //matching properties to verify correct mapping 
       }; 

      _mockedRepository 
       .Setup(x => x.Create(Moq.It.IsAny<Account>(_account))) 
       //here, we capture the actual account passed in. 
       .Callback<Account>(x=> _actualAccount = x) 
       .Returns(_account); 
     }; 

    Because of =() => _result = _accountCreator.Create(_newAccount); 

    It should_create_the_account_in_the_repository = 
     () => _result.ShouldEqual(_account); 

    It should_create_the_expected_account = 
     () => _expectedAccount.ToExpectedObject().ShouldEqual(_actualAccount); 
} 

उम्मीद वस्तु पैटर्न महान है, लेकिन यह सी # में लागू करने के लिए जटिल है, तो मैं एक पुस्तकालय है कि मेरे लिए यह सब संभालती है का उपयोग करें। https://github.com/derekgreer/expectedObjects

मेरा अंतिम अवलोकन वास्तविक खाते में संपत्तियों को देखता है और प्रत्येक "अपेक्षित वस्तु" पर एक ही संपत्ति के साथ तुलना करता है। इस तरह मेरे पास नकली संपत्ति जांच की एक बड़ी सूची नहीं है, न ही मेरे पास परीक्षण अवलोकन का एक टन है।