MOQ-模拟MVC控制器';s响应.Cookies.Clear()
本文关键字:Cookies 响应 Clear MVC 模拟 控制器 MOQ- | 更新日期: 2023-09-27 18:26:39
我是MOQ的新手,但我将它与NUnit一起用于单元测试。
我的控制器的所有部分都被嘲笑了,除了下面一行抛出"Object not set to a instance of a Object"错误消息。
Response.Cookies.Clear();
我有下面的扩展方法来模拟控制器上下文,它适用于我迄今为止遇到的其他一切(非常感谢这个论坛上的好人)。
public static int SetUpForTest(this System.Web.Mvc.Controller ctl, string username, TestingUtility.Roles role)
{
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url);
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method
//
// Mock the controller context (using the objects mocked above)
//
var moqCtx = new Mock<ControllerContext>(context.Object, new RouteData(), ctl);
moqCtx.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(username);
moqCtx.SetupGet(p => p.HttpContext.User.Identity.IsAuthenticated).Returns(true);
if (!string.IsNullOrEmpty(role.ToString()))
moqCtx.Setup(p => p.HttpContext.User.IsInRole(role.ToString())).Returns(true);
//
// Pass the mocked ControllerContext and create UrlHelper for the controller and return
//
ctl.ControllerContext = moqCtx.Object;
ctl.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);
return 1;
}
正如你在上面看到的,我试图嘲笑cookie集合的"get",但这无济于事。
此外,不能模拟实际的Clear()方法,因为它不是一个虚拟方法。
显然,我不想测试cookie是否被清除,我只想在测试中忽略它。
谢谢,
Greg
当我做cookie时,这对我很有用。清除()
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url);
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method
context.SetupGet(p => p.User.Identity.Name).Returns("blah");
context.SetupGet(p => p.User.Identity.IsAuthenticated).Returns(true);
var rc = new RequestContext(context.Object, new RouteData());
controller.ControllerContext = new ControllerContext(rc, controller);
参考以前的问题及其在不使用ActionContext的情况下的准确解决方案:如何在ASP.NET 5(MVC 6)中使用Response属性对Controller操作进行单元测试?[副本]
模仿HttpResponse和HttpContext是困难的,因为它们只是只读类型。因此,要模拟这些,请在HttpResponse和HttpContext上使用SetupGet,然后将HttpContext引用传递给ControllerContext。
var headerDict = new HeaderDictionary();
var httpResponse = new Mock<HttpResponse>();
var httpContext = new Mock<HttpContext>();
httpRespnse.SetupGet(=>c.Headers).Returns(headerDict);
httpContext.SetupGet(=>c.Response).Returns(httpResponse.Object);
var controllerContext = new ControllerContext()
{
HttpContext = httpContext.Object
};
var controllerInstance = new ValueController()
{
ControllerContext = controllerContext
};
(这只是半个答案,但对于注释字段来说太大了…)
您对new HttpCookieCollection()
的嘲讽是正确的。此代码在分离中工作:
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url);
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method
// Here clearing the cookies works just fine:
var instance = context.Object;
instance.Response.Cookies.Clear();
所以错误不在那里,而是在其他地方。如果您在代码中注释掉了带有Response.Cookies.Clear()
的行,会发生什么?那么其他的嘲笑都对吗?当您调试测试时,您能看到mock的其余部分如预期的那样吗?如果是的话,我会很惊讶(但我以前也很惊讶…)。