在异步方法中测试异常

时间:2017-03-14 15:26:49

标签: c# async-await nunit fluent-assertions

我对此代码感兴趣(这是一个示例):

Reservation.where('block_id IS NULL OR block_id != ?', 'something')
           .tap do |relation|
                  # Depending on your version of Rails you can do 
                  where_values = relation.where_values
                  # Or
                  where_values = relation.values[:where]
                  # With the first probably being better
                  where_values.delete_if { |where| ... }
                end
           .where(block_id: 'anything')

代码没有捕获异常,并且

失败
  

预计会抛出System.Exception,但没有例外   抛出。

我确定我错过了什么,但是文档似乎暗示这是要走的路。一些帮助将不胜感激。

2 个答案:

答案 0 :(得分:71)

您应该使用Func<Task>代替Action

[Test]
public void TestFail()
{
    Func<Task> f = async () => { await Fail(); };
    f.ShouldThrow<Exception>();            
}

这将调用以下用于验证异步方法的扩展

public static ExceptionAssertions<TException> ShouldThrow<TException>(
    this Func<Task> asyncAction, string because = "", params object[] becauseArgs)
        where TException : Exception        

在内部,此方法将运行Func返回的任务并等待它。像

这样的东西
try
{
    Task.Run(asyncAction).Wait();
}
catch (Exception exception)
{
    // get actual exception if it wrapped in AggregateException
}

请注意,测试本身是同步的。

答案 1 :(得分:7)

使用Fluent Assertions v5 +,代码将类似于:

ISubject sut = BuildSut();
//Act and Assert
Func<Task> sutMethod = async () => { await sut.SutMethod("whatEverArgument"); };
sutMethod.Should().ThrowAsync<Exception>();

这应该有效。