C# 异步方法中异常的测试

C# 异步方法中异常的测试,c#,async-await,nunit,fluent-assertions,C#,Async Await,Nunit,Fluent Assertions,我有点被这段代码卡住了(这是一个示例): 公共异步任务失败() { 等待任务。运行(()=>{throw new Exception();}); } [测试] 公共异步任务TestFail() { 动作a=async()=>{await Fail();}; a、 shouldtown(); } 代码没有捕获异常,并以失败告终 应引发System.Exception,但未引发异常 扔 我肯定我遗漏了一些东西,但医生们似乎认为这是一条出路。希望您能提供一些帮助。您应该使用Func而不是Action

我有点被这段代码卡住了(这是一个示例):

公共异步任务失败()
{
等待任务。运行(()=>{throw new Exception();});
}
[测试]
公共异步任务TestFail()
{
动作a=async()=>{await Fail();};
a、 shouldtown();
}
代码没有捕获异常,并以失败告终

应引发System.Exception,但未引发异常 扔

我肯定我遗漏了一些东西,但医生们似乎认为这是一条出路。希望您能提供一些帮助。

您应该使用
Func
而不是
Action

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

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

对于Fluent Assertions v5+来说,代码如下所示:

ISubject sut = BuildSut();
//Act and Assert
Func<Task> sutMethod = async () => { await sut.SutMethod("whatEverArgument"); };
await sutMethod.Should().ThrowAsync<Exception>();
ISubject sut=BuildSut();
//行动和主张
Func sutMethod=async()=>{await sut.sutMethod(“whatEverArgument”);};
等待sutMethod.Should().ThrowAsync();

这应该行。

好的,谢谢。错过。但是没有解决问题。问题是什么?@stuartd实际上,不,在测试异步方法时需要异步。ShouldThrow不是异步的。这可能是原因吗?您的问题是
操作
-这会创建一个
异步void
方法。正确的异步委托等价物是
Func
Fail
没有理由调用
任务。运行
,它只会引发异常,
TestFail
没有理由使用匿名方法,您只需对委托使用
Fail
,而无需将其包装在另一个不起任何作用的方法调用中。是否确实需要异步等待?似乎与just
Func f=()=>Fail()配合很好如果您有兴趣在测试之前等待调用完成执行。FYI-在最新版本(v5)的fluentassertions中,语法为:f.Should().throw如果
ShouldThrow
方法等待结果任务,那么如果您在函数中等待它,则不重要。应该这样做吗?不知道它是新的还是当时已经可用,但表示也可以使用该操作。即使我因为某种原因不能让它工作。难道没有等待的缺失吗<代码>等待sutMethod.Should().ThrowAsync()我认为在第三行中,async await关键字对是不必要的,如果没有它,它对我也适用。@Károly Ozsvárt:我认为它对你适用,因为你正在测试的代码没有一个在达到预期抛出之前需要继续的等待。这对于方法中的验证代码来说是很常见的(因为它通常首先出现),并且在测试中也是很常见的,因为可能会模拟所有依赖项以返回已完成的任务。但是,如果您点击一个continuation,它将不起作用也对我有用。我认为这只是一个阻塞,在我的测试中,这是一个阻塞调用,我很好。如何测试消息?等待sutMethod.Should().ThrowAsync().WithMessage(“AlaMaKota”)?
public static ExceptionAssertions<TException> ShouldThrow<TException>(
    this Func<Task> asyncAction, string because = "", params object[] becauseArgs)
        where TException : Exception        
try
{
    Task.Run(asyncAction).Wait();
}
catch (Exception exception)
{
    // get actual exception if it wrapped in AggregateException
}
ISubject sut = BuildSut();
//Act and Assert
Func<Task> sutMethod = async () => { await sut.SutMethod("whatEverArgument"); };
await sutMethod.Should().ThrowAsync<Exception>();