MSUnit测试异步地狱

时间:2017-05-22 19:24:52

标签: c# unit-testing async-await mstest

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

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

问题出在我选择Run Selected TestsRun All时。如果它们遵循开头提到的条件,那么许多测试将失败。任何只返回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;
}

1 个答案:

答案 0 :(得分:1)

解决方案使用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;
}