Reputation: 1317
I am trying to port a test to NUnit3 and am getting a System.ArgumentException : 'async void' methods are not supported, please use 'async Task' instead.
[Test]
public void InvalidUsername()
{
...
var exception = Assert.Throws<HttpResponseException>(async () => await client.LoginAsync("[email protected]", testpassword));
exception.HttpResponseMessage.StatusCode.ShouldEqual(HttpStatusCode.BadRequest); // according to http://tools.ietf.org/html/rfc6749#section-5.2
...
}
Assert.Throws()
appears to take a TestDelegate
, defined as:
public delegate void TestDelegate();
hence the ArgumentException
. What is the best way to port this code?
Upvotes: 74
Views: 33018
Reputation: 1477
This was resolved by Nunit. You can now use Assert.ThrowsAsync<>().
https://github.com/nunit/nunit/issues/1190
Example:
Assert.ThrowsAsync<Exception>(() => YourAsyncMethod());
Upvotes: 125
Reputation: 2407
I would recommend the following code instead of Assert.ThrowsAsync
, as this is more readable:
// Option A
[Test]
public void YourAsyncMethod_Throws_YourException_A()
{
// Act
AsyncTestDelegate act = () => YourAsyncMethod();
// Assert
Assert.That(act, Throws.TypeOf<YourException>());
}
// Option B (local function)
[Test]
public void YourAsyncMethod_Throws_YourException_B()
{
// Act
Task Act() => YourAsyncMethod();
// Assert
Assert.That(Act, Throws.TypeOf<YourException>());
}
Upvotes: 14
Reputation: 231
I ended up writing a static function that mirrors what NUnit does. There was a whole conversation at https://github.com/nunit/nunit/issues/464 about this.
public static async Task<T> Throws<T>(Func<Task> code) where T : Exception
{
var actual = default(T);
try
{
await code();
Assert.Fail($"Expected exception of type: {typeof (T)}");
}
catch (T rex)
{
actual = rex;
}
catch (Exception ex)
{
Assert.Fail($"Expected exception of type: {typeof(T)} but was {ex.GetType()} instead");
}
return actual;
}
Then from my tests I can use it such as
var ex = await CustomAsserts.Throws<HttpResponseException>(async () => await client.DoThings());
Assert.IsTrue(ex.Response.StatusCode == HttpStatusCode.BadRequest);
Upvotes: 1
Reputation: 67
To ensure the exception was thrown, it's better to not assert in the catch block if you so choose to use one. This way, you can be sure the correct exception type is thrown because otherwise you'll get a null reference or an uncaught different exception.
HttpResponseException expectedException = null;
try
{
await client.LoginAsync("[email protected]", testpassword));
}
catch (HttpResponseException ex)
{
expectedException = ex;
}
Assert.AreEqual(HttpStatusCode.NoContent, expectedException.Response.BadRequest);
Upvotes: 0
Reputation: 1
You could try using something like this:
try
{
await client.LoginAsync("[email protected]", testpassword);
}
catch (Exception ex)
{
Assert.That(ex, Is.InstanceOf(typeof (HttpResponseException)));
}
Upvotes: -5