Unit testing async method for specific exception

You can use an async Task unit test with the regular ExpectedExceptionAttribute:

[TestMethod]
[ExpectedException(typeof(DivideByZeroException))]
public async Task DivideTest1()
{
  int Result = await AsyncMathsStatic.Divide(4, 0);
}

Update from comment: ExpectedExceptionAttribute on Win8 unit test projects has been replaced with Assert.ThrowsException, which is nicely undocumented AFAICT. This is a good change design-wise, but I don't know why it's only supported on Win8.

Well, assuming that there's no async-compatible Assert.ThrowsException (I can't tell if there is one or not due to lack of documentation), you could build one yourself:

public static class AssertEx
{
  public async Task ThrowsExceptionAsync<TException>(Func<Task> code)
  {
    try
    {
      await code();
    }
    catch (Exception ex)
    {
      if (ex.GetType() == typeof(TException))
        return;
      throw new AssertFailedException("Incorrect type; expected ... got ...", ex);
    }

    throw new AssertFailedException("Did not see expected exception ...");
  }
}

and then use it as such:

[TestMethod]
public async Task DivideTest1()
{
  await AssertEx.ThrowsException<DivideByZeroException>(async () => { 
      int Result = await AsyncMathsStatic.Divide(4, 0);
  });
}

Note that my example here is just doing an exact check for the exception type; you may prefer to allow descendant types as well.

Update 2012-11-29: Opened a UserVoice suggestion to add this to Visual Studio.


[TestMethod]
public void DivideTest1()
{
    Func<Task> action = async () => { int Result = await AsyncMathsStatic.Divide(4, 0); });
    action.ShouldThrow<DivideByZeroException>();
}

Using .ShouldThrow() from FluentAssertions nuget package works for me


With the addition of the ThrowsExceptionAsync method, this is now covered natively without the need for third parties or extension methods in MSTest:

await Assert.ThrowsExceptionAsync<Exception>(() => { Fail(); });