मैं एक टास्क वापस करने के लिए मो को कैसे बता सकता हूं?


327

मुझे एक इंटरफ़ेस मिला है जो घोषित करता है

Task DoSomethingAsync();

मैं अपने परीक्षणों के लिए MoqFramework का उपयोग कर रहा हूं:

[TestMethod()]
public async Task MyAsyncTest()
{
   Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
   mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
   ...
}

फिर अपने परीक्षण में मैं उस कोड को कार्यान्वित करता हूं जो आह्वान करता है await DoSomethingAsync()। और परीक्षण उस रेखा पर विफल हो जाता है। मैं क्या गलत कर रहा हूं?


5
जब आप उस लाइन पर परीक्षण त्रुटियों को कहते हैं, तो यह किस त्रुटि का उत्पादन करता है?
अलसकी

@AlSki संभवतः एक NullReferenceException है। जैसा कि आप यहाँ
LuckyLikey

जवाबों:


709

आपकी विधि में कोई कॉलबैक नहीं है इसलिए उपयोग करने का कोई कारण नहीं है .CallBack()। आप बस का उपयोग कर वांछित मूल्यों के साथ एक टास्क लौट सकते हैं .Returns()और Task.FromResult , जैसे:

MyType someValue=...;
mock.Setup(arg=>arg.DoSomethingAsync())        
    .Returns(Task.FromResult(someValue));

अपडेट 2014-06-22

Moq 4.2 की सहायता के लिए दो नए विस्तार विधियाँ हैं।

mock.Setup(arg=>arg.DoSomethingAsync())
    .ReturnsAsync(someValue);

mock.Setup(arg=>arg.DoSomethingAsync())        
    .ThrowsAsync(new InvalidOperationException());

अपडेट 2016-05-05

जैसा कि सेठ फूल अन्य उत्तर में उल्लेख करते हैं , ReturnsAsyncकेवल उन तरीकों के लिए उपलब्ध है जो वापस लौटते हैं Task<T>। केवल टास्क लौटाने वाले तरीकों के लिए,

.Returns(Task.FromResult(default(object)))

इस्तेमाल किया जा सकता है।

जैसा कि इस उत्तर में दिखाया गया है , .NET 4.6 में यह सरल है .Returns(Task.CompletedTask);, जैसे:

mock.Setup(arg=>arg.DoSomethingAsync())        
    .Returns(Task.CompletedTask);

16
.Returns (Task.CompletedTask); वह मेरा जवाब था
टोड वेंस

8
यह उत्तर अप-टू-डेट रखने के लिए धन्यवाद, क्योंकि Moq ढांचे को अपडेट मिला है!
याकूब स्टैम

.Returns(Task.FromResult(default(object))रिटर्न प्रकार शून्य होने पर अच्छी तरह से काम करता है। .Returns(Task.FromResult(null as MyType))अच्छी तरह से काम करता है जब अपेक्षित वापसी प्रकार अशक्त होता है।
जेरेमी रे ब्राउन

1
@JeremyRayBrown जैसा कि मैं समझाता हूं, .NET 4.6 default(object)में अब जरूरत नहीं है। एक संदर्भ प्रकार के null as MyTypeरूप default(MyType)में लंबे समय के रूप MyTypeमें ही है।
पनियागोटिस कानावोस

40

इसी तरह का मुद्दा

मेरे पास एक इंटरफ़ेस है जो मोटे तौर पर दिखता है:

Task DoSomething(int arg);

लक्षण

जब मेरी सेवा परीक्षण awaitedकॉल के तहत मेरी इकाई परीक्षण विफल हो गया DoSomething

ठीक कर

स्वीकृत उत्तर के विपरीत, आप इस पद्धति में इस पद्धति .ReturnsAsync()पर कॉल करने में असमर्थ Setup()हैं, क्योंकि विधि गैर-जेनेरिक की Taskबजाय लौटाती है Task<T>

हालाँकि, आप अभी भी .Returns(Task.FromResult(default(object)))सेटअप पर उपयोग कर सकते हैं , जिससे परीक्षण पास हो सकता है।


1
इस पर बस एक विचार, अगर आपको गैर-जेनेरिक कार्य (नॉन .net 4.6) वापस करने की आवश्यकता है, तो मैं टास्क को वापस करने के लिए एक आसान तरीका के रूप में Task.Delay (1) को वापस करने पर विचार करूंगा। आप समय तर्क को बढ़ाकर भी काम की नकल कर सकते हैं।
स्टीवेथथ्रेड

26

आपको .Returns(Task.FromResult(0));कॉलबैक के बाद केवल जोड़ना होगा ।

उदाहरण:

mock.Setup(arg => arg.DoSomethingAsync())
    .Callback(() => { <my code here> })
    .Returns(Task.FromResult(0));

4

अब आप Talentsoft.Moq.SetupAsync पैकेज https://github.com/TalentSoft/Moq.SetupAsync का भी उपयोग कर सकते हैं

यहाँ पर मिले उत्तरों के आधार पर और विचारों ने Moq को प्रस्तावित किया, लेकिन अभी भी यहाँ लागू नहीं किया गया है: https://github.com/moq/moq4/issues/384 , async विधियों के सेटअप को बहुत सरल करें

पिछले प्रतिक्रियाओं में SetupAsync एक्सटेंशन के साथ किए गए कुछ उदाहरण मिले:

mock.SetupAsync(arg=>arg.DoSomethingAsync());
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.