【问题标题】:Integration testing ASP.NET MVC when async异步时集成测试 ASP.NET MVC
【发布时间】:2018-02-27 00:32:20
【问题描述】:

我正在寻找有关为 SUT 包含异步 ASP.NET 操作的复杂集成测试设置同步上下文的指导。

我有一个模拟 HttpContext 并且可以执行同步操作方法。但是异步操作通常会因 HttpContext.Current 为空而失败。通过阅读,我认为我需要调用 SynchronizationContext.SetSynchronizationContext 以便在异步操作进行时将 HttpContext.Current 从一个线程“移动”到另一个线程。

我试过了:

  • 类似于this 的简单 TestSynchronizationContext - 仍然失败,并显示为空 HttpContext.Current
  • 使用反射实例化 AspNetSynchronizationContext - 尚未管理,因为类和依赖项是内部的,这使得这非常困难

有什么建议吗?

【问题讨论】:

    标签: c# asp.net-mvc unit-testing async-await


    【解决方案1】:

    您应该能够使用几乎任何调用主测试线程上所有代码的同步上下文。这样,您的人工HttpContext.Current 将对所有代码可见。

    它的工作方式是有一个内部Queue<Action>。初始操作已运行并且可以将其他内容排队。队列被排空,直到所有未完成的工作完成。 SynchronizationContext 有一个未完成操作的概念,它本质上是一个整数计数器。

    NitoAsync 项目是一个流行的异步扩展库。它包含这样一个同步上下文(我手边没有类名;grep 表示 SynchronizationContext)。

    【讨论】:

    • 谢谢你。这看起来很有希望。当我在 SpecFlow 框架中运行验收测试时,我想我必须确保在每个异步测试步骤结束时“队列已耗尽”,然后再继续下一步。
    • 我查看了 Nito.AsyncEx,但找不到合适的 SynchronizationContext。我用它来“grep”它:github.com/StephenCleary/AsyncEx/find/v4
    • @MrBlueSky 我想我找到了。它被称为 AsyncContext。 github.com/StephenCleary/AsyncEx/wiki/AsyncContext
    • 谢谢,@usr。我试过这个,还有来自github.com/antiufo/Shaman.SingleThreadSynchronizationContext 的另一个类似的解决方案。无论出于何种原因,我仍然遇到间歇性 null HttpContext.Current。
    • 我通过抽象出对 IHttpContextFactory 后面的 HttpContext.Current 的访问并从我的 HttpContextFactory 引用捕获的模拟上下文 (nuget.org/packages/HttpSimulator) 解决了我的情况。 (所以我不得不对生产代码进行更改,而我并不想这样做。)
    猜你喜欢
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多