2012-06-27 29 views
17

मैं यह पता लगाने की कोशिश कर रहा हूं कि एसिंक को कैसे लागू करें और मेरे xUnit परीक्षणों में कीवर्ड का इंतजार कैसे करें। मैं xUnit 1.9 और Async सीटीपी 1.3 का उपयोग कर रहा हूँ। यहाँ मेरी परीक्षण का मामला हैxUnit और Moq async का समर्थन नहीं करते हैं - कीवर्ड का इंतजार करें

मैं एक अंतरफलक जो एक अतुल्यकालिक विधि कॉल निर्दिष्ट करता है

public interface IDoStuffAsync 
{ 
    Task AnAsyncMethod(string value); 
} 

मैं एक वर्ग है जो इंटरफेस की खपत और async प्रणाली को बुलाती है

public class UseAnAsyncThing 
{ 
    private readonly IDoStuffAsync _doStuffAsync; 

    public UseAnAsyncThing(IDoStuffAsync doStuffAsync) 
    { 
     _doStuffAsync = doStuffAsync; 
    } 

    public async Task DoThatAsyncOperation(string theValue) 
    { 
     await _doStuffAsync.AnAsyncMethod(theValue); 
    } 
} 

मेरी परीक्षणों में है मैं यह जांचना चाहते हैं कि विधि DoThatAsyncOperation विधि को सही मान के साथ बुला रही है, इसलिए मैं इंटरफ़ेस का मज़ाक उड़ाता हूं और कॉल को सत्यापित करने के लिए Moq का उपयोग करता हूं

[Fact] 
    public async void The_test_will_pass_even_though_it_should_fail() 
    { 
     var mock = new Mock<IDoStuffAsync>(); 
     var sut = new UseAnAsyncThing(mock.Object); 

     mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>())); 

     await sut.DoThatAsyncOperation("test"); 

     // This won't throw a Moq.MockExcpetion so the test appears to pass 
     // However it does not run 
     mock.Verify(x => x.AnAsyncMethod("fail")); 
    } 

यह परीक्षण async और await कीवर्ड का उपयोग कर रहा है। जब यह चलता है तो यह गलत तरीके से गुजरता है क्योंकि मोक को यह कहना चाहिए कि सत्यापन विफल रहता है। sut.DoThatAsyncOperation("test"); करने के लिए कॉल के बाद किसी भी कोड नहीं चलता है

[Fact] 
    public void This_will_work_and_assert_the_reslt() 
    { 
     var mock = new Mock<IDoStuffAsync>(); 
     var sut = new UseAnAsyncThing(mock.Object); 

     mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>())); 

     sut.DoThatAsyncOperation("test").ContinueWith(y => { }); 

     // This won't throw a Moq.MockExcpetion so the test appears to pass 
     // However it does not run 
     mock.Verify(x => x.AnAsyncMethod("fail")); 
    } 

इस परीक्षण का इंतजार है और async खोजशब्दों के बिना सेटअप है और ठीक से गुजरता है।

क्या यह xUnit और Moq के लिए अपेक्षित व्यवहार है?


अद्यतन

स्टीफन टिप्पणी के लिए धन्यवाद मैं दो बदलाव करके पहले टेस्ट को ठीक करने में कामयाब रहे। परीक्षण अब शून्य के बजाए एक कार्य देता है और मॉक भी एक कार्य देता है।

[Fact] 
    public async Task The_test_will_pass_even_though_it_should_fail() 
    { 
     var mock = new Mock<IDoStuffAsync>(); 
     var sut = new UseAnAsyncThing(mock.Object); 

     mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>())).ReturnAsync(true); 

     await sut.DoThatAsyncOperation("test"); 

     // This now fails as it should 
     mock.Verify(x => x.AnAsyncMethod("fail")); 
    } 
+3

ऊपर अद्यतन पैरा के लिए धन्यवाद:

var tcs = new TaskCompletionSource<T>(); tcs.SetResult(default(T)); mock.Setup(x => x.AnAsyncMethod(It.IsAny<T>())).Returns(tcs.Task); 

तो यह है कि मैं 'वापसी' विधि बदलना पड़ा ठीक करने के लिए। TaskCompletionSource वह कुंजी था जिसे मैं MOQ का उपयोग करके अपने एसिंक विधि को मॉक करने में ढूंढ रहा था। – Philippe

+0

इसके बजाय स्पष्ट रूप से एक TaskCompletionSource बनाने की आप बस Task.FromResult इस्तेमाल कर सकते हैं: 'mock.Setup (x => x.AnAsyncMethod (It.IsAny ())) रिटर्न्स (Task.FromResult (सही));' – sapphiremirage

+0

। आप mock.Setup (x => x.AnAsyncMethod (It.IsAny ()) का भी उपयोग कर सकते हैं)। ReturnAsync (true); कार्य को स्थापित करने से बचने के लिए –

उत्तर

14

void के बजाय Task लौटने के लिए अपनी इकाई परीक्षण विधि बदलें, और यह काम करना चाहिए। async void इकाई परीक्षण is being considered for a future release के लिए समर्थन।

मैं अपने ब्लॉग पर विस्तार से why async unit tests don't work by default का वर्णन करता हूं। (मेरे ब्लॉग उदाहरण एमएसटीएस्ट का उपयोग करते हैं, लेकिन xUnit pre-1.9 सहित अन्य सभी परीक्षण धावक में भी यही समस्याएं मौजूद थीं)।

+0

टिप के लिए धन्यवाद लेकिन यह भी विफल रहता है। मॉक विधि को चलाते समय इस बार एक NullRefException फेंकता है। मुझे लगता है कि नकली को एक कार्य वापस करना है। –

+0

वास्तव में मुझे जवाब में ले जाता है। अब मैं नकली से कार्यसंगठन स्रोत लौटकर परीक्षा उत्तीर्ण कर सकता हूं। –

+5

आप एक ही चीज़ के लिए 'टास्क.फ्रॉम रिसेट' का उपयोग शॉर्टेंड के रूप में भी कर सकते हैं। –

3

मैंने आपके 'अपडेट' से कोड का उपयोग करने की कोशिश की, लेकिन यह उस एसिंक विधि पर रोक रहा था जिसे मैं मजाक कर रहा था।

mock.Setup(x => x.AnAsyncMethod(It.IsAny<T>())).Returns(()=> { return tcs.Task; }); 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^