Does anyone have an example of how to unit test an async method in a Windows 8 Metro application, to ensure that it throws the required exception?
Given a class with an async method
public static class AsyncMathsStatic { private const int DELAY = 500; public static async Task<int> Divide(int A, int B) { await Task.Delay(DELAY); if (B == 0) throw new DivideByZeroException(); else return A / B; } }
I want to write a test method using the new Async.ExpectsException construction. I've tried :-
[TestMethod] public void DivideTest1() { Assert.ThrowsException<DivideByZeroException>(async () => { int Result = await AsyncMathsStatic.Divide(4, 0); }); }
but of course the test doesn't wait for the async method to complete, and so results in a failed test that the exception hasn't been thrown.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With