How to handle exceptions thrown by Tasks in xUnit .net's Assert.Throws?

后端 未结 2 491
Happy的楠姐
Happy的楠姐 2021-01-01 15:54

The following asynchronous xUnit.net test with a lambda marked with the async modifier fails by reporting that no exception was thrown

2条回答
  •  不思量自难忘°
    2021-01-01 16:14

    Update

    This has been solved in xUnit 2, with the addition of Assert.ThrowsAsync.


    I am suspecting that Assert.Throws is not async-aware. I recommend raising this issue with the xUnit team, suggesting a ThrowsAsync be added.

    An async delegate in this case is returning Task or Task, and the ArgumentNullException is not thrown out of the delegate directly; instead, it is placed on the Task (Task.Exception.InnerException). Assert.Throws is expecting the exception to be thrown out of the delegate directly, not placed on a property of the return value.

    You can create your own AssertEx.ThrowsAsync as such:

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

    which can be used as such:

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

    I use a similar approach in MSTest.

提交回复
热议问题