2013-03-12 5 views
7

मिलान नहीं इस कोड:Moq It.Is <>

hub.MockedUserRepository.Setup(r => r.Update(It.IsAny<ControllUser>())) 
         .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null))) 
         .Verifiable(); 

प्रिंट होगा

शून्य = सच

तो मैं इस मेल का उपयोग करके वे इसके शिकार हो सोच रहा हूँ:

var zombieDisconnectParameterMatcher = It.Is<ControllUser>(x => x.Zombies[0].ConnectionId == null); 
hub.MockedUserRepository.Setup(r => r.Update(zombieDisconnectParameterMatcher)) 
         .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null))) 
         .Verifiable(); 

लेकिन यह नहीं करता है ।

क्यों?

उत्तर

9

source code of It पर देखकर, इसे अभिव्यक्ति पेड़ों के साथ करना होगा। मुझे सवाल पसंद है; वे काफी परेशान हो सकते हैं। आप निम्न विधि परिभाषाओं पर एक नज़र डालें चाहते हैं:

public static TValue It.Is<TValue>(Expression<Func<TValue, bool>> match) 
{ 
     return Match<TValue>.Create(
       value => match.Compile().Invoke(value), 
       () => It.Is<TValue>(match)); 
} 

public static T Match.Create<T>(Predicate<T> condition, Expression<Func<T>> renderExpression) 
{ 
     // ... 
     return default(T); 
} 

आप निम्नलिखित लाइन पर अमल चाहते हैं:

var zombieDisconnectParameterMatcher = It.Is<ControllUser>(x => x.Zombies[0].ConnectionId == null); 

फिर It.Is<ControllUser>() एक विधि Match.Create<ControllUser>() कहा जाता है, जिनमें से डिफ़ॉल्ट रिटर्न फोन करने की कोशिश करेंगे ControllUser। मुझे लगता है कि ControllUser एक वर्ग है और इसलिए zombieDisconnectParameterMatchernull होगा। आपको इसे डीबगर के साथ देखने में सक्षम होना चाहिए। तो क्या वास्तव में आप कॉल कर रहे है:

hub.MockedUserRepository.Setup(r => r.Update(null)) 
    .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null))) 
    .Verifiable(); 

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

इस समस्या को हल करने के लिए, या तो zombieDisconnectParameterMatcher परिवर्तनीय इनलाइन करें, या इसे एक अभिव्यक्ति टाइपेड चर (उदाहरण के लिए Expression<Func<...>>) बनाएं। उत्तरार्द्ध यह सुनिश्चित करेगा कि कोड निष्पादित नहीं किया गया है, लेकिन एक अभिव्यक्ति के रूप में माना जाता है जो नकली ढांचे के बारे में तर्क दे सकता है ('UpdateZombies[0].ConnectionId == null के साथ बुलाया जा रहा है?)।

+0

मैं आपको सम्मान में धनुष देता हूं, सर @ करमीरियल। – fernandoespinosa

1

यह निर्भर करता है कि ControllUser उदाहरण तत्काल है। यदि आपके द्वारा नकली के भीतर संदर्भित उदाहरण परीक्षण के तहत कोड में निर्दिष्ट वास्तविक उदाहरण नहीं है, तो Setup विफल हो जाएगा। आपको यह सुनिश्चित करने की आवश्यकता होगी कि परीक्षण के तहत कोड में ControllUser का उदाहरण एक ही ऑब्जेक्ट परीक्षण कोड में से एक के रूप में है। यदि ऐसा नहीं है, तो आपको It.IsAny<ControllUser>() और कॉलबैक का उपयोग करके इसके लिए परीक्षण करना होगा, क्योंकि आपका पहला उदाहरण दिखाता है। आपके द्वारा परीक्षण किए जा रहे कोड के अधिक देखे बिना निश्चितता के साथ कहना मुश्किल है।