如何处理任务中的xUnit .NET的Assert.Throws抛出的异常 ?(How to

2019-07-17 16:54发布

下面的异步xUnit.net与测试lambda标有async修改失败,通过报告,没有异常被抛出:

    [Theory, AutoWebData]
    public async Task SearchWithNullQueryThrows(
        SearchService sut,
        CancellationToken dummyToken)
    {
        // Fixture setup
        // Exercise system and verify outcome
        Assert.Throws<ArgumentNullException>(async () =>
            await sut.SearchAsync(null, dummyToken));
        // Teardown
    }

为了确保一个ArgumentNullException实际上是扔我明确地使用了try-catch块。 它的工作,但生成的代码是不干净的(与第一次测试):

[Theory, AutoWebData]
public async Task SearchWithNullQueryThrows(
    SearchService sut,
    CancellationToken dummyToken)
{
    // Fixture setup
    var expected = typeof(ArgumentNullException);
    Type actual = null;
    // Exercise system
    try
    {
        await sut.SearchAsync(null, dummyToken);
    }
    catch (ArgumentNullException e)
    {
        actual = e.GetType();
    }
    // Verify outcome
    Assert.Equal(expected, actual);
    // Teardown
}

为什么Assert.Throws<T>lambda标有async修改失败?

Answer 1:

更新

这已经解决了的xUnit 2,增加的Assert.ThrowsAsync


我怀疑Assert.Throws不是async知晓。 我建议提出这类问题的xUnit的团队,表明ThrowsAsync添加。

一个async在这种情况下代表在返回TaskTask<T>并且ArgumentNullException不抛出直接委托的; 相反,它被放置在TaskTask.Exception.InnerException )。 Assert.Throws期待的异常被抛出的代表直接,而不是放置在返回值的属性的。

你可以创建自己的AssertEx.ThrowsAsync这样:

public static async Task ThrowsAsync<TException>(Func<Task> func)
{
  var expected = typeof(TException);
  Type actual = null;
  try
  {
    await func();
  }
  catch (Exception e)
  {
    actual = e.GetType();
  }
  Assert.Equal(expected, actual);
}

这可被用作这样的:

[Theory, AutoWebData]
public async Task SearchWithNullQueryThrows(
    SearchService sut,
    CancellationToken dummyToken)
{
    // Fixture setup
    // Exercise system and verify outcome
    await AssertEx.ThrowsAsync<ArgumentNullException>(async () =>
        await sut.SearchAsync(null, dummyToken));
    // Teardown
}

我使用MSTest的类似的方法。



Answer 2:

如果您还需要返回例外验证它那么这可能是有用的:

public static async Task<Exception> AssertThrowsAsync<TException>(Func<Task> func)
    {
        var expected = typeof (TException);
        Exception exception = null;
        Type actual = null;
        try
        {
            await func();
        }
        catch (Exception e)
        {
            actual = e.GetType();
            exception = e;
        }
        Assert.NotNull(exception);
        Assert.Equal(expected, actual);
        return exception;
    }


文章来源: How to handle exceptions thrown by Tasks in xUnit .net's Assert.Throws?