Reputation: 11957
I just upgraded to NUnit 3, and I'm having some trouble getting my unit tests to pass.
[Test]
public void GetSomethingAsync_CallsConverter()
{
int id = 123;
Assert.Catch<NullReferenceException>(
async () => await _repository.GetSomethingAsync(id));
_fooMock.Verify(f => f.Bar(id), Times.Once);
}
NUnit gives me this error:
System.ArgumentException : 'async void' methods are not supported, please use 'async Task' instead
I managed to get my Assert.Throws
to pass by changing it like this:
Assert.Throws<NullReferenceException>(
async () => await _repository.GetSomethingAsync(id));
//to
Assert.That(
async () => await _repository.GetSomethingAsync(id),
Throws.InstanceOf<NullReferenceException>());
But there's no similar equivalent thing to Assert.Catch
.
So how are we supposed to use Assert.Catch
on async methods?
Upvotes: 3
Views: 3237
Reputation: 777
I had a similar issue and I replaced the void return with Task so
Try replacing
[Test]
public void GetSomethingAsync_CallsConverter()
with
[Test]
public async Task GetSomethingAsync_CallsConverter()
So here is a example of how we are testing async calls
[Test]
public async System.Threading.Tasks.Task Integration_Get_Invalid_ReturnsUnauthorized()
{
// ARRANGE
const string url = "/api/v2/authenticate/999/wrongName/wrongPassword";
// ACT
var result = await Get(url);
// ASSERT
Assert.IsFalse(result.HttpResponseMessage.IsSuccessStatusCode);
}
If you want to test that an exception is being raised use the following
Assert.Throws<ValidationException>(() =>
{
var user = await _service.Get(2);
});
Upvotes: 4
Reputation: 457197
I use my own AssertEx.ThrowsAsync
method, since various unit testing frameworks / assertion libraries have varying amounts of support for async
:
[Test]
public async Task GetSomethingAsync_CallsConverter()
{
int id = 123;
await AssertEx.ThrowsAsync<NullReferenceException>(
async () => await _repository.GetSomethingAsync(id));
_fooMock.Verify(f => f.Bar(id), Times.Once);
}
A fix is coming for NUnit. Unfortunately, they've chosen to implement it with a sync-over-async pattern, which I believe is a mistake that will come back to bite them later.
Upvotes: 2