MSUnit 测试异步地狱

MSUnit Testing Async Hell

我有一个 async Task 单元测试(MVC、c#、.NET 4.5.2)。它在 aysnc Task<ActionResult> 方法上执行 await,而后者又对异步方法有 await 调用。

如果我 select 他们并在 Visual Studio 2017 年从右键菜单中选择 Debug Selected Tests,测试和其他类似测试将通过。

问题出在我selectRun Selected TestsRun All时。届时,如果它们遵循开头提到的条件,许多测试将失败。任何只有 returns 一个 RedirectToRouteResult 而没有进行上述深入分析的测试都将通过。

[TestMethod]
public async Task TestPartsController_GetPartInfo_ReturnsInfo()
{
   //arrange
   PartController pc = new PartController();

   //act
   var result = await pc.GetPartInfo("PC123456");

   //assert
   Assert.IsIntanceOfType(result, typeof(ViewResult));
   Assert.AreEqual("Form", ((ViewResult)result).ViewName);
   Assert.AreEqual("PC123456", result.Model.PartNum.ToUpper());
}

public async Task<ActionResult> GetPartInfo(string partNum)
{
   if (string.IsNullOrEmpty(partNum)
   {
      return RedirectToAction("Index")
   }

   var response = await ServiceClient.GetJsonAsync("/part/partinfo", "?partNum=" + partNum;
   response.EnsureSuccessStatusCode();
   results = await response.Content.ReadAsAsync<Dto.PartNumInfo>();
   ...
   return View("Form", model);
}

public async Task<HttpResponseMessage> GetAsync(Controllers controller, string criteria)
{
   HttpClient client;
   string service = GetService(controller, out client);
   var response = await client.GetAsync(service + criteria);
   return response;
}

解决方案 一直使用 async/await 以及使用语句和 IDisposable。

 public async Task<HttpResponseMessage> GetJsonAsync<T>(Controllers controller, T data)
 {
    HttpResponseMessage response;

    using (var service = new MyService())
    {
       HttpClient http;
       string serviceLoc = service.GetServiceClient(controller, out http);
       response = await http.GetAsync(serviceLoc, data);
    }

    return response;
}

解决方案一直使用 async/await 以及使用语句和 IDisposable。

public async Task<HttpResponseMessage> GetJsonAsync<T>(Controllers controller, T data)
{
    HttpResponseMessage response;

    using (var service = new MyService())
    {
       HttpClient http;
       string serviceLoc = service.GetServiceClient(controller, out http);
       response = await http.GetAsync(serviceLoc, data);
    }

    return response;
}