Testing for exceptions in async methods
C#Async AwaitNunitFluent AssertionsC# Problem Overview
I'm a bit stuck with this code (this is a sample):
public async Task Fail()
{
await Task.Run(() => { throw new Exception(); });
}
[Test]
public async Task TestFail()
{
Action a = async () => { await Fail(); };
a.ShouldThrow<Exception>();
}
The code doesn't catch the exception, and fails with > Expected a System.Exception to be thrown, but no exception was > thrown.
I'm sure I'm missing something, but docs seem to suggest this is the way to go. Some help would be appreciated.
C# Solutions
Solution 1 - C#
You should use Func<Task>
instead of Action
:
[Test]
public void TestFail()
{
Func<Task> f = async () => { await Fail(); };
f.ShouldThrow<Exception>();
}
That will call the following extension which is used to verify asynchronous methods
public static ExceptionAssertions<TException> ShouldThrow<TException>(
this Func<Task> asyncAction, string because = "", params object[] becauseArgs)
where TException : Exception
Internally this method will run task returned by Func
and wait for it. Something like
try
{
Task.Run(asyncAction).Wait();
}
catch (Exception exception)
{
// get actual exception if it wrapped in AggregateException
}
Note that test itself is synchronous.
Solution 2 - C#
With Fluent Assertions v5+ the code will be like :
ISubject sut = BuildSut();
//Act and Assert
Func<Task> sutMethod = async () => { await sut.SutMethod("whatEverArgument"); };
await sutMethod.Should().ThrowAsync<Exception>();
This should work.
Solution 3 - C#
Other variation of usage ThrowAsync method:
await Should.ThrowAsync<Exception>(async () => await Fail());