如何使用异步方法使用Assert.Catch

时间:2016-02-23 14:25:06

标签: c# async-await nunit-3.0

我刚刚升级到NUnit 3,我在通过单元测试时遇到了一些麻烦。

[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给了我这个错误:

  

System.ArgumentException:&#39; async void&#39;方法不受支持,请使用&#39; async Task&#39;代替

我设法让我的Assert.Throws通过改变它:

    Assert.Throws<NullReferenceException>(
        async () => await _repository.GetSomethingAsync(id));
//to
    Assert.That(
        async () => await _repository.GetSomethingAsync(id),
        Throws.InstanceOf<NullReferenceException>());

Assert.Catch没有类似的东西 那么我们如何在异步方法上使用Assert.Catch呢?

2 个答案:

答案 0 :(得分:4)

我有一个类似的问题,我用Task替换了void返回

尝试替换

[Test]
public void GetSomethingAsync_CallsConverter()

[Test]
public async Task GetSomethingAsync_CallsConverter()

以下是我们如何测试异步调用的示例

[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); 
}

如果要测试是否引发了异常,请使用以下

Assert.Throws<ValidationException>(() =>
{
    var user = await _service.Get(2);
 });

答案 1 :(得分:2)

我使用自己的AssertEx.ThrowsAsync method,因为各种单元测试框架/断言库对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);
}

NUnit的fix is coming。不幸的是,他们选择使用同步异步模式来实现它,我认为这是一个错误,以后会再次咬它们。