Asp.net mvc 如何将会话添加到模拟httpcontext?
根据scott hanselman的模拟示例,我尝试使用模拟助手模拟httpcontext,代码片段如下Asp.net mvc 如何将会话添加到模拟httpcontext?,asp.net-mvc,unit-testing,Asp.net Mvc,Unit Testing,根据scott hanselman的模拟示例,我尝试使用模拟助手模拟httpcontext,代码片段如下 controller = GetAccountController(); ActionResult result = controller.ChangePassword(); HttpContextBase hb = MvcMockHelpers.FakeHttpContext("~/Account/ChangePassword"); hb.Session.Add("id", 5);
controller = GetAccountController();
ActionResult result = controller.ChangePassword();
HttpContextBase hb = MvcMockHelpers.FakeHttpContext("~/Account/ChangePassword");
hb.Session.Add("id", 5);
// Assert Assert.AreEqual(5, (int)hb.Session["id"]);
我注意到会话没有被添加,也没有收到任何错误。会话对象的属性的值低于此值
Count=0,CodePage=0,Content=null,iscookeless=null,IsNewSession=null,IsReadOnly=null,IsSynchronized=null,Keys=null,LCID=0,Mode=off,SessionId=null,Static Objects=null,SynRoot=null,TimeOut=0
对于Rhino mock和Moq,我得到了相同的结果
请告诉我如何将会话添加到模拟httpcontext
提前感谢。您引用的代码解释了如何伪造httpcontext-当您调用“hb.Session.Add”时,它实际上没有做任何事情-它只是阻止测试失败,因为它依赖于HttpContext。您引用的代码解释了如何伪造HttpContext-当您调用“hb.Session.Add”时,它实际上没有做任何事情-它只是阻止测试失败,因为它依赖于HttpContext。以下是我用来模拟的内容,不仅是会话,还有您需要的大多数其他对象(请求、响应等),此代码是Steve Sanderson和其他人以及我自己的代码的集合,请注意,会话是使用字典伪造的
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;
namespace ECWeb2.UnitTests {
public class ContextMocks {
public Moq.Mock<HttpContextBase> HttpContext { get; private set; }
public Moq.Mock<HttpRequestBase> Request { get; private set; }
public Moq.Mock<HttpResponseBase> Response { get; private set; }
public RouteData RouteData { get; private set; }
public ContextMocks(Controller onController) {
// Define all the common context objects, plus relationships between them
HttpContext = new Moq.Mock<HttpContextBase>();
Request = new Moq.Mock<HttpRequestBase>();
Response = new Moq.Mock<HttpResponseBase>();
HttpContext.Setup(x => x.Request).Returns(Request.Object);
HttpContext.Setup(x => x.Response).Returns(Response.Object);
HttpContext.Setup(x => x.Session).Returns(new FakeSessionState());
Request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
Response.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
Request.Setup(x => x.QueryString).Returns(new NameValueCollection());
Request.Setup(x => x.Form).Returns(new NameValueCollection());
// Apply the mock context to the supplied controller instance
RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
onController.ControllerContext = new ControllerContext(rc, onController);
onController.Url = new UrlHelper(rc);
}
ContextMocks() {
}
// Use a fake HttpSessionStateBase, because it's hard to mock it with Moq
private class FakeSessionState : HttpSessionStateBase {
Dictionary<string, object> items = new Dictionary<string, object>();
public override object this[string name] {
get { return items.ContainsKey(name) ? items[name] : null; }
set { items[name] = value; }
}
}
}
使用System.Collections.Generic;
使用System.Collections.Specialized;
使用System.Web;
使用System.Web.Routing;
使用System.Web.Mvc;
命名空间ECWeb2.UnitTests{
公共类contextmock{
public Moq.Mock HttpContext{get;private set;}
公共Moq.Mock请求{get;private set;}
公共Moq.Mock响应{get;private set;}
公共路由数据路由数据{get;私有集;}
公共上下文模拟(控制器onController){
//定义所有公共上下文对象,以及它们之间的关系
HttpContext=new Moq.Mock();
请求=新的Moq.Mock();
响应=新Moq.Mock();
Setup(x=>x.Request).Returns(Request.Object);
Setup(x=>x.Response).Returns(Response.Object);
Setup(x=>x.Session).Returns(new FakeSessionState());
Request.Setup(x=>x.Cookies).Returns(新的HttpCookieCollection());
Response.Setup(x=>x.Cookies).Returns(新的HttpCookieCollection());
Setup(x=>x.QueryString).Returns(newnamevalueCollection());
Setup(x=>x.Form).Returns(newNameValueCollection());
//将模拟上下文应用于提供的控制器实例
RequestContext rc=newrequestcontext(HttpContext.Object,newroutedata());
onController.ControllerContext=新的ControllerContext(rc,onController);
Url=newurlHelper(rc);
}
ContextMocks(){
}
//使用一个假的HttpSessionStateBase,因为很难用Moq来模拟它
私有类FakeSessionState:HttpSessionStateBase{
字典项=新字典();
公共重写对象[字符串名称]{
获取{return items.ContainsKey(name)→items[name]:null;}
设置{items[name]=value;}
}
}
}
}以下是我用来模拟会话的内容,以及您需要的大多数其他对象(请求、响应等),这些代码是Steve Sanderson和其他人以及我自己的代码的集合,请注意,会话是使用字典伪造的
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;
namespace ECWeb2.UnitTests {
public class ContextMocks {
public Moq.Mock<HttpContextBase> HttpContext { get; private set; }
public Moq.Mock<HttpRequestBase> Request { get; private set; }
public Moq.Mock<HttpResponseBase> Response { get; private set; }
public RouteData RouteData { get; private set; }
public ContextMocks(Controller onController) {
// Define all the common context objects, plus relationships between them
HttpContext = new Moq.Mock<HttpContextBase>();
Request = new Moq.Mock<HttpRequestBase>();
Response = new Moq.Mock<HttpResponseBase>();
HttpContext.Setup(x => x.Request).Returns(Request.Object);
HttpContext.Setup(x => x.Response).Returns(Response.Object);
HttpContext.Setup(x => x.Session).Returns(new FakeSessionState());
Request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
Response.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
Request.Setup(x => x.QueryString).Returns(new NameValueCollection());
Request.Setup(x => x.Form).Returns(new NameValueCollection());
// Apply the mock context to the supplied controller instance
RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
onController.ControllerContext = new ControllerContext(rc, onController);
onController.Url = new UrlHelper(rc);
}
ContextMocks() {
}
// Use a fake HttpSessionStateBase, because it's hard to mock it with Moq
private class FakeSessionState : HttpSessionStateBase {
Dictionary<string, object> items = new Dictionary<string, object>();
public override object this[string name] {
get { return items.ContainsKey(name) ? items[name] : null; }
set { items[name] = value; }
}
}
}
使用System.Collections.Generic;
使用System.Collections.Specialized;
使用System.Web;
使用System.Web.Routing;
使用System.Web.Mvc;
命名空间ECWeb2.UnitTests{
公共类contextmock{
public Moq.Mock HttpContext{get;private set;}
公共Moq.Mock请求{get;private set;}
公共Moq.Mock响应{get;private set;}
公共路由数据路由数据{get;私有集;}
公共上下文模拟(控制器onController){
//定义所有公共上下文对象,以及它们之间的关系
HttpContext=new Moq.Mock();
请求=新的Moq.Mock();
响应=新Moq.Mock();
Setup(x=>x.Request).Returns(Request.Object);
Setup(x=>x.Response).Returns(Response.Object);
Setup(x=>x.Session).Returns(new FakeSessionState());
Request.Setup(x=>x.Cookies).Returns(新的HttpCookieCollection());
Response.Setup(x=>x.Cookies).Returns(新的HttpCookieCollection());
Setup(x=>x.QueryString).Returns(newnamevalueCollection());
Setup(x=>x.Form).Returns(newNameValueCollection());
//将模拟上下文应用于提供的控制器实例
RequestContext rc=newrequestcontext(HttpContext.Object,newroutedata());
onController.ControllerContext=新的ControllerContext(rc,onController);
Url=newurlHelper(rc);
}
ContextMocks(){
}
//使用一个假的HttpSessionStateBase,因为很难用Moq来模拟它
私有类FakeSessionState:HttpSessionStateBase{
字典项=新字典();
公共重写对象[字符串名称]{
获取{return items.ContainsKey(name)→items[name]:null;}
设置{items[name]=value;}
}
}
}
}/P>< P>您可以使用OutTrror基金会提供的MVC控件库来模拟处理正常请求时可用的其他会话状态和其他对象(HypReQuest,HttpResponse等)。
(或使用NuGet下载) 它包含帮助您快速创建单元测试的 例如:[TestMethod]
public void TestSomething()
{
TestControllerBuilder builder = new TestControllerBuilder();
// Arrange
HomeController controller = new HomeController();
builder.InitializeController(controller);
// Act
ViewResult result = controller.About() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
使用MVC Contrib TestHelper库提供的TestControllerBuilder类型,您可以快速初始化控制器并初始化其内部数据成员(HttpContext、HttpSession、TempData…)
当然,HttpSessionState本身也是模拟的
private class MockHttpSession : HttpSessionStateBase
{
readonly Dictionary<string, object> _sessionDictionary = new Dictionary<string, object>();
public override object this[string name]
{
get
{
object obj = null;
_sessionDictionary.TryGetValue(name, out obj);
return obj;
}
set { _sessionDictionary[name] = value; }
}
}
private ControllerContext CreateMockedControllerContext()
{
var session = new MockHttpSession();
var controllerContext = new Mock<ControllerContext>();
controllerContext.Setup(m => m.HttpContext.Session).Returns(session);
return controllerContext.Object;
}
[TestMethod]
public void Index()
{
// Arrange
MyController controller = new MyController();
controller.ControllerContext = CreateMockedControllerContext();
// Act
ViewResult result = controller.Index() as ViewResult;
....
}