在异步委托中声明异常

h b*_*bob 3 c# nunit unit-testing asynchronous async-await

我正在使用NUnit3。我编写了一个扩展方法:

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

这使我可以这样做:

TestDelegate del = () => foo.doSomething(null);
del.ShouldThrow<ArgumentNullException>();
Run Code Online (Sandbox Code Playgroud)

现在我想要类似异步的东西:

AsyncTestDelegate del = async () => await foo.doSomething(null);
del.ShouldThrowAsync<ArgumentNullException>();
Run Code Online (Sandbox Code Playgroud)

所以我这样写:

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

但这不起作用:'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?)

我究竟做错了什么?

smo*_*nes 5

据我所知,Assert.ThrowsAsync不会返回Task,也无法等待。await从扩展方法中删除。

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

docs中的示例用法。请注意,Assert.ThrowsAsync返回a,MyException并且await在委托中。

[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 ) ); 
  }
}
Run Code Online (Sandbox Code Playgroud)