简体   繁体   中英

Asserting exceptions in async delegates

I'm using NUnit 3. I wrote an extension method:

public static T ShouldThrow<T>(this TestDelegate del) where T : Exception {
  return Assert.Throws(typeof(T), del) as T;
}

Which allows me to do this:

TestDelegate del = () => foo.doSomething(null);
del.ShouldThrow<ArgumentNullException>();

Now I want something similar for async:

AsyncTestDelegate del = async () => await foo.doSomething(null);
del.ShouldThrowAsync<ArgumentNullException>();

So I wrote this:

public static async Task<T> ShouldThrowAsync<T>(this AsyncTestDelegate del) where T : Exception {
  return (await Assert.ThrowsAsync(typeof(T), del)) as T;
}

But that doesn't work: 'Exception' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'Exception' could be found (are you missing a using directive or an assembly reference?) .

What am I doing wrong?

As far as I can tell, Assert.ThrowsAsync doesn't return a Task , and cannot be awaited. Remove await from your extension method.

public static T ShouldThrowAsync<T>(this AsyncTestDelegate del) where T : Exception {
  return Assert.ThrowsAsync(typeof(T), del) as T;
}

Example usage from the docs . Note that Assert.ThrowsAsync returns a MyException and that the await is in the delegate.

[TestFixture]
public class UsingReturnValue
{
  [Test]
  public async Task TestException()
  {
    MyException ex = Assert.ThrowsAsync<MyException>(async () => await MethodThatThrows());

    Assert.That( ex.Message, Is.EqualTo( "message" ) );
    Assert.That( ex.MyParam, Is.EqualTo( 42 ) ); 
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM