无法使用 Xunit 在异步方法中断言异常

Can't Assert exception in async method with Xunit

代码测试中的一些错误引起了这个问题,由于代码的扩展,这里是一个完整的项目,它完全复制了我们遇到的问题(以节省您分析大量行)。

问题是在尝试从异步方法捕获异常时,这里是 AsyncTest.cs 文件:

using System;
using Xunit;

namespace AsyncTest
{
    public class AsyncTest
    {
        [Fact]
        public void ProbeTest()
        {
            // Arrange
            var probe = new Probe();

            // Act
            Action action = async () =>
                await probe.GetJob();

            // Assert
            var ex = Assert.Throws<InvalidOperationException>(action);
            Assert.Contains("Trouble with Project.", ex.Message);
        }
    }
}

现在要测试的Probe.csclass(注意GetJob方法调用的GetById方法中的延迟和异常抛出):

using System;
using System.Threading.Tasks;

namespace AsyncTest
{
    class Probe
    {
        public async Task<MyResult<Guid>> GetJob()
        {
            var etlJob = await GetById("id");
            return new MyResult<Guid>(etlJob);
        }

        public async Task<Guid> GetById(string id)
        {
            await Task.Delay(200);

            throw new InvalidOperationException("Trouble with Project.");
        }
    }
}

最后,Probe.cs使用的MyResult.cs class。

namespace AsyncTest
{
    public class MyResult<T>
    {
        private T _value;

        public MyResult(T Value)
        {
            _value = Value;
        }

        public string Message { get; set; }
        public T Data { get; set; }
    }
}

显然,即使删除了 await Task.Delay(200); 行,测试也会在抛出异常之前结束。在某些情况下,使用多个断点并将调用置于循环中,抛出异常但测试未检测到。

看起来像是同步和异步的混淆,但无法弄清楚到底是什么。

提前致谢。

尝试使您的测试方法异步并等待断言:

    [Fact]
    public async Task ProbeTest()
    {
        // Arrange
        var probe = new Probe();

        // Act
        Func<Task> action = async () => await probe.GetJob();

        // Assert
        var ex = await Assert.ThrowsAsync<InvalidOperationException>(action);
        Assert.Contains("Trouble with Project.", ex.Message);
    }