2012-12-29 12 views
18

एक lambdaasync संशोधक के साथ चिह्नित के साथ निम्न अतुल्यकालिक xUnit.net परीक्षण रिपोर्टिंग है कि कोई अपवाद उत्पन्न हुआ था द्वारा विफल रहता है:xUnit .net के Assert में कार्य द्वारा फेंक दिया अपवादों को कैसे संभालें। <T>?

[Theory, AutoWebData] 
    public async Task SearchWithNullQueryThrows(
     SearchService sut, 
     CancellationToken dummyToken) 
    { 
     // Fixture setup 
     // Exercise system and verify outcome 
     Assert.Throws<ArgumentNullException>(async() => 
      await sut.SearchAsync(null, dummyToken)); 
     // Teardown 
    } 

यकीन है कि एक ArgumentNullException वास्तव में फेंक दिया जाता है कि मैं स्पष्ट रूप से एक try-catch ब्लॉक इस्तेमाल किया बनाने के लिए। यह काम किया, लेकिन जिसके परिणामस्वरूप कोड (पहले टेस्ट की तुलना में) साफ नहीं है:

[Theory, AutoWebData] 
public async Task SearchWithNullQueryThrows(
    SearchService sut, 
    CancellationToken dummyToken) 
{ 
    // Fixture setup 
    var expected = typeof(ArgumentNullException); 
    Type actual = null; 
    // Exercise system 
    try 
    { 
     await sut.SearchAsync(null, dummyToken); 
    } 
    catch (ArgumentNullException e) 
    { 
     actual = e.GetType(); 
    } 
    // Verify outcome 
    Assert.Equal(expected, actual); 
    // Teardown 
} 

क्यों lambda साथ Assert.Throws<T>async संशोधक के साथ चिह्नित विफल रहता है?

+3

यह एक ज्ञात समस्या है: http://xunit.codeplex.com/workitem/9799 – DaveShaw

+0

+1 यह ऐसा लगता है कि स्नैपशॉट '03e3be9a6781' में स्नैपशॉट' 16883cb2351f' से पहले है जहां रिलीज '2.0.0-अल्फा' जुड़ा हुआ है। हालांकि यह अभी भी NuGet पैकेज प्रबंधक के साथ समाधान अद्यतन करने के बाद काम नहीं करता है। –

उत्तर

33

अद्यतन

यह XUnit 2 में हल किया गया है, Assert.ThrowsAsync के योग के साथ।


मैं शक कर रहा हूँ कि Assert.Throwsasync -aware नहीं है। मैं इस समस्या को xUnit टीम के साथ बढ़ाने की सलाह देता हूं, जिसमें ThrowsAsync जोड़ा गया है।

इस मामले में एक async प्रतिनिधि Task या Task<T>, और ArgumentNullException प्रतिनिधि सीधे से बाहर फेंक दिया नहीं है लौटा रहा है; इसके बजाय, यह Task (Task.Exception.InnerException) पर रखा गया है। Assert.Throws प्रतिनिधि को सीधे प्रतिनिधि से बाहर निकाला जाने की उम्मीद है, वापसी मूल्य की संपत्ति पर नहीं रखा गया है।

public static async Task ThrowsAsync<TException>(Func<Task> func) 
{ 
    var expected = typeof(TException); 
    Type actual = null; 
    try 
    { 
    await func(); 
    } 
    catch (Exception e) 
    { 
    actual = e.GetType(); 
    } 
    Assert.Equal(expected, actual); 
} 

जो इस तरह के रूप में इस्तेमाल किया जा सकता है::

[Theory, AutoWebData] 
public async Task SearchWithNullQueryThrows(
    SearchService sut, 
    CancellationToken dummyToken) 
{ 
    // Fixture setup 
    // Exercise system and verify outcome 
    await AssertEx.ThrowsAsync<ArgumentNullException>(async() => 
     await sut.SearchAsync(null, dummyToken)); 
    // Teardown 
} 

मैं MSTest में एक समान दृष्टिकोण का उपयोग

आप अपनी खुद की AssertEx.ThrowsAsync जैसे बना सकते हैं।

+0

यह काम किया :) धन्यवाद! –

+0

मैंने आपके कोड को थोड़ा सा संशोधित किया, क्योंकि मेरा मानना ​​है कि यह केवल 'ArgumentNullException' खड़ा था, 'एसेर्ट' तक कभी भी प्राप्त होगा। एक और चीज जो विचार करने योग्य हो सकती है वह यह है कि मूल 'Assert.Throws' * रिटर्न * अपवाद (ताकि आप अपवाद संदेश का भी परीक्षण कर सकें, उदाहरण के लिए)। – Benjol

+0

यह भी देखें https://gist.github.com/Haacked/4616366 – Benjol

2

आप भी अपवाद वापस जाने के लिए तो यह सत्यापित करने के लिए की जरूरत है इस उपयोगी हो सकता है:

public static async Task<Exception> AssertThrowsAsync<TException>(Func<Task> func) 
    { 
     var expected = typeof (TException); 
     Exception exception = null; 
     Type actual = null; 
     try 
     { 
      await func(); 
     } 
     catch (Exception e) 
     { 
      actual = e.GetType(); 
      exception = e; 
     } 
     Assert.NotNull(exception); 
     Assert.Equal(expected, actual); 
     return exception; 
    } 
संबंधित मुद्दे