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

后端 未结 2 492
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<T>, 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<TException>(Func<Task> 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<ArgumentNullException>(async () =>
            await sut.SearchAsync(null, dummyToken));
        // Teardown
    }
    

    I use a similar approach in MSTest.

    0 讨论(0)
  • 2021-01-01 16:15

    If you also need to return the exception to verify it then this might be useful:

    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;
        }
    
    0 讨论(0)
提交回复
热议问题