96

So I have a test like the following:

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

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

To my surprise, Test1 passes successfully. To make it fail I have to write like this:

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

What is the purpose of ThrowsAsync(), if it does not work in the scenario above?

2 Answers 2

175

You're supposed to await the result (see xunit's acceptance tests for examples and alternate forms).

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

In this specific degenerate case, you could just return the Task that Assert.ThrowsAsync yields without using await; but in that case, the key thing is to yield the Task back to the xUnit framework, i.e.

[Fact]
Task Test1() =>
    Assert.ThrowsAsync<ArgumentNullException>(MethodThatThrows);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I can never remember that the await goes at the front of the line!
46

Just in case anyone wants to separate Act and Assert part, below code can be used:

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

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

1 Comment

@neoscribe, a better way imo, is to make it async.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.