【问题标题】:How to initialize Request object in MVC unit tests?如何在 MVC 单元测试中初始化 Request 对象?
【发布时间】:2014-01-23 05:16:21
【问题描述】:

我有以下控制器方法:

public ActionResult Contact()
{
  HttpPostedFileBase theFile = Reqeust.Files["myfile"];
  ViewBag.Message = "Contact Page";
  return View();
}

在单元测试中,我这样做:

HomeController controller = new HomeController();
controller.Contact();

调用 Contact() 时,请求将为空。我尝试了多种不同的方法来初始化 Request 对象,但没有任何效果。我已经尝试过 HttpContextWrapper() 但没有任何东西可以转换为 HttpRequestBase。此外,controller.Request 是只读的,因此我创建的任何 HttpContext.Current 都无法在那里工作。

有什么想法吗?

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    您需要模拟它并设置 ControllerContext。假设您选择了Moq 作为这样的框架来简化事情。您的测试可能如下所示

    // arrange
    var mockHttpContext = new Mock<HttpContextBase>();
    var response = new Mock<HttpResponseBase>();
    mockHttpContext.SetupGet(x => x.Response).Returns(response.Object);
    
    var controller = new HomeController()
    {
        ControllerContext = new ControllerContext() 
        { 
            HttpContext = mockHttpContext.Object 
        }
    };
    
    // act    
    controller.Contact();
    
    // assert
    

    当然,如果您希望 Request 对象的 Files 属性返回一些内容,您需要为模拟设置正确的期望值。目前,您的控制器操作似乎对此文件没有任何用处。我猜在您的真实代码中,此控制器操作实际上适用于上传的文件。因此,您将模拟 HttpPostedFileBase,然后您可以断言其上的某些方法已被调用,或者您需要验证此操作的正确行为。

    【讨论】:

    • 我注意到您为响应编码。我只是将其更改为 Request 并且它也有效。你能详细说明一下这对 HttpPostedFileBase 是如何工作的吗?
    【解决方案2】:

    在您的测试中实例化您的控制器时,您可以向它传递一个新的ControllerContext,其中包括一个模拟HttpContext + 模拟Request

    controller = new HomeController {
        ControllerContext = new ControllerContext { HttpContext = new MockHttpContext() }
    };
    

    或者,您可以使用MoqRhinoMocks 之类的框架。

    【讨论】:

      猜你喜欢
      • 2016-07-13
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多