Asp.net mvc 如何使用ASP.NET MVC的MOQ模拟Request.ServerVariables?
当我开始学习mock和其他框架时,我正在学习为我的asp.NETMVC进行单元测试 经过检查,我发现最低起订量似乎是最容易获得的。 到目前为止,我一直在尝试模拟Request.ServerVariables,因为我已经了解到最好将它们抽象到属性中 因此:Asp.net mvc 如何使用ASP.NET MVC的MOQ模拟Request.ServerVariables?,asp.net-mvc,unit-testing,moq,Asp.net Mvc,Unit Testing,Moq,当我开始学习mock和其他框架时,我正在学习为我的asp.NETMVC进行单元测试 经过检查,我发现最低起订量似乎是最容易获得的。 到目前为止,我一直在尝试模拟Request.ServerVariables,因为我已经了解到最好将它们抽象到属性中 因此: /// <summary> /// Return the server port /// </summary> protected string ServerPort
/// <summary>
/// Return the server port
/// </summary>
protected string ServerPort
{
get
{
return Request.ServerVariables.Get("SERVER_PORT");
}
}
问题:
所以基本上我已经输入了所有的引用,并且使用这个函数我能够让它工作。我还没有使用mvcmockhelpers类,因为我仍在尝试学习所有这些 对于任何有兴趣了解我是如何解决这个问题的人,这就是我使用的代码
[Test]
public void Create_Returns_ViewResult_On_Success()
{
var server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.Setup(x => x.ApplicationPath).Returns("/");
request.Setup(x => x.Url).Returns(new Uri("http://localhost"));
request.Setup(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection{
{ "SERVER_NAME", "localhost" },
{ "SCRIPT_NAME", "localhost" },
{ "SERVER_PORT", "80" },
{ "HTTPS", "www.melaos.com" },
{ "REMOTE_ADDR", "127.0.0.1" },
{ "REMOTE_HOST", "127.0.0.1" }
});
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Server).Returns(server.Object);
var controller = new HomeController();
//MvcMockHelpers.SetFakeControllerContext(controller);
controller.ControllerContext = new ControllerContext(context. Object, new RouteData(), controller);
var results = controller.Create();
Assert.IsNotNull(results);
Assert.IsInstanceOf(typeof(ViewResult), results);
}
[测试]
public void Create_在_Success()上返回_ViewResult_
{
var server=newmock(MockBehavior.Loose);
var响应=新模拟(MockBehavior.Strict);
var request=newmock(MockBehavior.Strict);
Setup(x=>x.ApplicationPath)。返回(“/”;
Setup(x=>x.Url).Returns(新Uri(“http://localhost"));
request.Setup(x=>x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection{
{“服务器名称”,“本地主机”},
{“脚本名称”,“本地主机”},
{“服务器端口”,“80”},
{“HTTPS”,“www.melaos.com”},
{“远程地址”,“127.0.0.1”},
{“远程主机”,“127.0.0.1”}
});
var context=newmock();
SetupGet(x=>x.Request).Returns(Request.Object);
SetupGet(x=>x.Response).Returns(Response.Object);
SetupGet(x=>x.Server).Returns(Server.Object);
var controller=新的HomeController();
//MvcMockHelpers.SetFakeControllerContext(控制器);
controller.ControllerContext=新的ControllerContext(context.Object,new RouteData(),controller);
var results=controller.Create();
Assert.IsNotNull(结果);
Assert.IsInstanceOf(typeof(ViewResult),results);
}
因为我想模拟HttpContext,而不是HttpContextBase,所以我试图找到一种方法将HttpContextBase模拟对象转换为HttpContext,但发现这是不可能的
HttpContext
这是经典的asp.net上下文。问题是它
没有基类且不是虚拟的,因此无法用于测试
(不能嘲笑它)。建议不要将其作为函数传递
参数,而是传递HttpContextBase类型的变量
HttpContextBase
这是(c#3.5的新版本)对HttpContext的替代。既然是
抽象地说,它现在是可以模仿的。这个想法是你的功能
expected to passed上下文应该期望接收其中一个。
它由HttpContextWrapper具体实现
HttpContextWrapper
在C#3.5中也是新的—这是
HttpContextBase。要在普通网页中创建其中一个,请使用“新建”
HttpContextWrapper(HttpContext.Current)
其思想是,为了使代码单元可测试,您需要声明所有
HttpContextBase类型的变量和函数参数,以及
使用IOC框架,如Castle Windsor,将其注入。正常情况下
代码,castle是注入“new”的等价物
HttpContextWrapper(HttpContext.Current)’,而在测试代码中
将获得HttpContextBase的模拟
(来源:)
所以我改变了调用代码的方式
从使用HttpContext开始:
public static string GetIpAddress(HttpContext currentContext) {
...
}
要使用HttpContextBase
:
public static string GetIpAddress(HttpContextBase currentContext) {
...
}
当我使用该方法时,我用HttpContextWrapper包装HttpContext,如下所示:
var ip = GeneralUtil.GetIpAddress(new HttpContextWrapper(HttpContext.Current));
现在,您可以通过以下方式轻松模拟HttpContextBase
var ip = GeneralUtil.GetIpAddress(new HttpContextWrapper(HttpContext.Current));