Xunit Assert.ThrowsAsync() работает неправильно?

Итак, у меня есть тест вроде следующего:

    [Fact]
    public void Test1()
    {
        Assert.ThrowsAsync<ArgumentNullException>(() => MethodThatThrows());
    }

    private async Task MethodThatThrows()
    {
        await Task.Delay(100);
        throw new NotImplementedException();
    }

К моему удивлению, Test1 успешно проходит. Чтобы это не получилось, я должен написать вот так:

Assert.Throws<ArgumentNullException>(() => MethodThatThrows().Wait());

Какова цель ThrowsAsync(), если она не работает в описанном выше сценарии?

Ответ 1

Вы должны await получить результат (см. приемочные тесты xunit).

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

В этом конкретном вырожденном случае вы можете просто return Task, который Assert.ThrowsAsync выводит без использования await, но главное, что вам нужно передать результирующий Task обратно в инфраструктуру xUnit, то есть

[Fact]
public Task Test1() =>
    Assert.ThrowsAsync<ArgumentNullException>(MethodThatThrows);

Ответ 2

На случай, если кто-то захочет разделить часть Act и Assert, можно использовать следующий код:

//Act
Task result() => systemUnderTest.AsyncMethodThatThrows();

//Assert
await Assert.ThrowsAsync<Exception>(result);