ControllerContext.HttpContext单元测试的初始化

时间:2013-04-08 14:55:50

标签: c# asp.net-mvc-3 unit-testing controller

在为Controller编写单元测试的过程中,我需要设置或初始化 -

ControllerContext.HttpContext.Request.QueryString

设置此项的最简单方法是什么,以便我可以实际传递 - ControllerContext.HttpContext.Request.QueryString - 并对控制器进行测试?

1 个答案:

答案 0 :(得分:7)

您可以使用模拟框架来模拟控制器正在使用的HttpContext。

例如NSubstitute

// arrange
var contextMock = Substitute.For<HttpContextBase>();
var requestMock = Substitute.For<HttpRequestBase>();
var queryString = new NameValueCollection();
queryString["foo"] = "bar";
requestMock.QueryString.Returns(queryString);
contextMock.Request.Returns(requestMock);
var sut = new SomeController();
sut.ControllerContext = new ControllerContext(contextMock, new RouteData(), sut);

// act
var actual = sut.SomeAction(); 

// assert
...

当然,您可以使用任何其他您喜欢的模拟框架,例如Moq或Rhino Mocks,以模拟HttpContext。

顺便说一句,如果你使用了视图模型(你应该总是在一个设计合理的ASP.NET MVC应用程序中),你甚至都不关心Request.QueryString,因为你的控制器动作现在将视图模型作为参数:

public ActionResult SomeAction(MyViewModel model)
{
    ...
}

并且默认模型绑定器会考虑请求参数与模型的绑定。您应该避免在控制器操作中编写管道代码,您可以从查询字符串和内容中提取一些数据。

看看您的单元测试现在变得多可读:

var model = new MyViewModel();
model.Foo = "bar";
var sut = new SomeController();

// act
var actual = sut.SomeAction(model); 

// assert
...

请参阅?您不再需要关心管道代码了。