如何对调用异步方法的同步方法进行单元测试?

时间:2012-09-28 13:39:41

标签: unit-testing asynchronous synchronous async-await

为调用异步方法的同步方法编写单元测试的正确方法是什么。 现在我的单元测试正在通过,但是当我尝试打开页面时,它永远不会返回。 为什么我的单元测试失败了?我怎么能让它失败?

我用这个简单的代码复制了我的问题:

我的通过考试:

   [TestMethod]
   public void DoSomeWork_WhenWeDoSomeWork_ShouldReturnDone()
   {
      var service = new SyncService();

      const string expected = "Done";
      var actual = service.DoSomeWork();

      Assert.AreEqual(expected, actual);

   }

我永远不会回来的观点:

    public ActionResult Index()
    {
       var syncService = new SyncService();

        return View((object)syncService.DoSomeWork());
    }

我永远不会回来查看的服务:

    public class SyncService
    {
       public string DoSomeWork()
       {
          return SomeWork().GetAwaiter().GetResult();
       }

       private async Task<string> SomeWork()
       {
          var task1 = Task.Delay(1000);
          var task2 = Task.Delay(1000);

          await Task.WhenAll(task1, task2);

          return "Done";
       }
    }

2 个答案:

答案 0 :(得分:1)

我认为我不能用这个具体的例子来帮助你,但我认为一个好的总体策略是编写两个测试。一个用于测试同步方法是否传递正确的数据,另一个用于测试异步方法是否正常工作。

我主要使用JavaScript,一般方法适用于我。您也可以查看测试框架的文档,也许它提供了一些方法。

答案 1 :(得分:0)

首先,don't block on async code(链接到我的博客)。通过阻止async代码,您实际上会导致死锁。这种死锁不会发生在您的单元测试中,因为unit tests run in a thread pool context, not an ASP.NET context(链接到我的博客)。

good reasons for not having synchronous wrappers for asynchronous methods。所以我建议完全删除DoSomeWork,只留下SomeWork(重命名为SomeWorkAsync)。

要解决您的问题,您应该使用asynchronous controller actions