【问题标题】:How to do integration tests on an mvc controller that calls httpcontext.current如何在调用 httpcontext.current 的 mvc 控制器上进行集成测试
【发布时间】:2016-12-06 14:39:07
【问题描述】:

我需要在每个方法中调用 HttpContext.Current 的 ASP.Net MVC 控制器上进行集成测试。我已经尝试了各种方法并进行了大量研究,尽管我觉得我缺少一些东西。我走了以下路线:

  • Asp.Net 核心:我发现使用由 Stefan Steiger (How to get HttpContext.Current in ASP.NET Core?) 提供的 asp.net 核心测试主机来解决堆栈溢出问题。这是一个很好的解决方案。但是,在尝试实施和进一步阅读时,似乎这仅适用于 aspnetcore 控制器并且不向后兼容。我知道有一个 shim,但是我找不到任何关于如何使用它的说明。
  • 使用批处理文件启动 iis express 并进行调用。我用这种方法遇到的问题是我需要能够在测试中进行调试。我尝试附加视觉工作室调试器,但是由于某种原因这不起作用。我一直在断点处收到消息“当前不会命中断点。没有为此文档加载任何符号”。
  • 我还研究了如何以编程方式使用测试控制器启动项目,但找不到如何以编程方式启动 Visual Studio Web 项目。 (希望通过进程和 msbuild 启动它)
  • 目前我正在使用 owin self 主机进行测试,但是,控制器中的 HttpContext.Current 为空(显然)。如果有办法解决这个问题,这是最可取的方法。

任何关于如何完成这些测试的建议将不胜感激。

谢谢,

编辑,我使用以下方法附加:

 private static bool AttachToIIS(int tries = 10, int threadsleep = 500)
    {
        System.Threading.Thread.Sleep(1000);
        bool isAttached = false;
        int count = 0;
        while (isAttached == false && count < tries)
        {
            _DTE dte = (_DTE)Marshal.GetActiveObject("VisualStudio.DTE.14.0");
            Processes processes = dte.ActiveWindow.DTE.Debugger.LocalProcesses;
            foreach (EnvDTE.Process process in processes)
            {
                System.Diagnostics.Debug.WriteLine("process: " + process.Name);
                try
                {
                    if (process.Name.Contains("iis"))
                    {
                        process.Attach();
                        isAttached = true;
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e.Message);
                }
            }
            System.Threading.Thread.Sleep(threadsleep);
            count++;
        }
        return isAttached;
    }

一个奇怪的是,当我附加到调试器时(我不是 COM 专家),它附加了首先打开的 Visual Studio 实例的调试器。

【问题讨论】:

  • 更新:我走的是启动 iis express 并附加调试器的路线。诀窍是在一个线程上运行 iis,在另一个线程上运行请求;控制器被命中并可调试,并且 httpcontext.current 不为空。但是,只有在运行测试之前运行 iis 时才会发生这种情况。因此,当我在没有 iis 已经运行的情况下运行它时,控制器中的断点不会被命中,但是当测试在 iis 之前运行的情况下运行时会被命中。我确定这与流程有关。
  • 更新:我只是在后台启动 iis express 并保持运行;然后在单元测试中调用服务器。一个奇怪的是,当我附加到调试器时(我不是 COM 专家),它附加了首先打开的 Visual Studio 实例的调试器。

标签: c# asp.net asp.net-mvc httpcontext


【解决方案1】:

根据为什么您使用HttpContext.Current,您可以修改您的代码以改用Controller 类的HttpContext 属性。

然后您可以为您的测试创建一个自定义的ControllerContext,它也可以包含一个 HTTP 上下文。请注意,MVC 比旧的 ASP.NET 更智能,因为它使用 HttpContextBase,您可以在测试中继承甚至模拟完全自定义的 HTTP 上下文。

相关链接:

【讨论】:

  • 谢谢,我们最终只是更改了控制器端点,使用 ioc 容器注入接口的“shim”实现,该接口在测试时返回 IHttpContextManager 的测试版本(返回 HttpContext),以及运行时的实际当前 HttpContext。再次感谢!!!
猜你喜欢
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多