在 xunit 的任务中测试抛出异常的函数

Test a function throwing an Exception in a Task in xunit

我想使用 xunit 测试一个 运行 一个任务的函数并投入那个任务 例如:

public void doSomething(){
     Task.Run(() =>
            {
                throw new ArgumentNullException();
            });
}

当我想通过这样做来测试这个功能时:

[Fact]
public void TestIfTheMethodThrow()
{
   Assert.Throws<ArgumentNullException>(() => doSomething()); // should return true but return false                                                                   
}

我希望 Task.Run() 完全完成,然后断言才能完成。有人有解决方案吗?

使用 TPL(任务库)引发和处理异常与“标准”异常处理略有不同。 只评估一个已完成的任务是有意义的,所以你需要等待完成,即使在这种情况下它是一个例外。

看看这篇 MSDN 文章 Exception handling (Task Parallel Library)

您有两个不同的选择:

  • .Wait() 添加到 Task.Run(...)`

    Task.Run(() =>
           {
               throw new ArgumentNullException();
           }).Wait();
    
    
    
  • 或等待任务完成while(!task.IsCompleted) {}

     var task = Task.Run(() =>
            {
                throw new ArgumentNullException();
            });
    while(!task.IsCompleted) {}

然后测试结果应该符合预期 - 抛出异常。

可能是,在 Wait 之前,您的测试偶尔会通过 - 不要生气 - 在这种情况下,任务执行速度比测试检查快 - 这是细微错误的危险来源.

您可以使用 asyncawait

编写您的方法

阅读本文以供参考Asynchronous programming with async and await

新方法是这样的,调用者会决定是否等待,如果你用await调用它会等待任务完成,否则它会继续而不等待任务完成

public async Task DoSomethingAsync()
{
    if (true)
        throw new ArgumentNullException();
    await FooAsync();
}

测试中:

[Fact]
public async Task TestIfTheMethodThrow()
{
   await Assert.ThrowsAsync<ArgumentNullException>(() => DoSomethingAsync());                
}