如何使用NUnit(或可能使用其他框架)测试异步方法?

akn*_*ds1 54 .net nunit unit-testing asynchronous async-await

我有一个ASP.NET Web API应用程序,带有一个ApiController,它具有异步方法,返回Task<>对象并用async关键字标记.

public class MyApiController : ApiController
{
    public async Task<MyData> GetDataById(string id)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如何为ApiController的异步方法编写NUnit测试?如果我需要使用另一个测试框架,我也会对此开放.我对.NET单元测试很新,所以我对学习最佳实践很感兴趣.

Jot*_*aBe 55

截至今天(2014年7月2日),异步测试得到以下支持:

在前两个框架​​中,测试方法必须具有以下签名:

[TestMethod]
public async Task MyTestMethod()
{
   ...
   var result = await objectUnderTest.TestedAsyncMethod(...);
   // Make assertions
}
Run Code Online (Sandbox Code Playgroud)

NUnit,除了那个签名,支持这个:

public async void MyTestMethod()
Run Code Online (Sandbox Code Playgroud)

当然,在任何这些测试方法中,您都可以使用它await来调用异步方法并等待它们.

如果您正在使用不支持异步测试方法的测试框架,那么,唯一的方法是调用异步方法并等待它使用任何常用方法完成运行:await,读取Result属性在Task<T>通过返回async方法,使用任何通常的方法等待Task等.等待之后,你可以照常做所有的断言.例如,使用MSTest:

[TestMethod]
public void MyTestMethod()
{
    ...
    Task<MyResultClass> task = objectUnderTest.MyAsyncMethod(...);
    // Make anything that waits for the method to end
    MyResultClass result = task.Result;

    // Make the assertions
    Assert.IsNotNull(result);
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 从 NUnit v3.x 开始,他们现在希望您拥有公共异步任务 Foo() 来进行返回 void 的测试 (5认同)

akn*_*ds1 15

在我看来,NUnit 2.6中没有内置支持来测试返回Tasks的异步方法.我现在能看到的最佳选择是使用Visual Studio自己的UnitTesting框架或xUnit.net 作为支持异步测试.

使用Visual Studio UnitTesting框架,我可以编写这样的异步测试:

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestAsyncMethods
{
    [TestMethod]
    public async Task TestGetBinBuildById()
    {
         ...
         var rslt = await obj.GetAsync();
         Assert.AreEqual(rslt, expected);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好消息是来自[NUnit 2.6.2](http://nunit.org/?p=releaseNotes&r=2.6.2)和[Resharper 7.1](http://youtrack.jetbrains.com/issue/RSRP)的支持-332732) (7认同)

Cha*_*lie 6

请记住,NUnit 2.6系列与之前的系列一样,是针对.NET 2.0框架而构建的.因此,在面向.NET 2.0的程序集中,NUnit只能执行您自己编写的相同内容.

具体来说,您无法将测试方法标记为异步,并期望NUnit对其执行任何特殊操作.

但是,你可以

  • 针对您的测试使用.NET 4.5.NUnit将在一个单独的进程中运行它们.
  • 在测试中使用await等待调用 异步方法的结果.

如果这是你所希望的,那么上述任何一个都不会给你异步测试执行.在等待异步操作完成时,不会执行任何其他测试.

另一种选择是使用NUnitLite.NUnitLite 0.8支持[Asynchronous]属性,允许在异步测试完成时继续进行其他测试.该属性的优点是它允许异步测试在.NET 2.0到4.0中工作

我们目前没有NUnitLite的.NET 4.5版本,但它很快就会添加,我们正在进行一项在该环境中使用[Asynchronous]可选的更改.目前,您可以轻松下载并重新编译.NET 4.5的源代码.

对于未来,请查看NUnit 3.0以完全支持异步方法,以及在多个线程或多个进程中一般并行执行测试.