2013-08-07 16 views
7

我是新来的最小起订量,但我用它与NUnit进行单元测试。最小起订量 - 模拟MVC控制器的Response.Cookies.Clear()

我有我的控制器的所有部分嘲笑,除了下面的行抛出'对象没有设置对象的实例'错误消息。

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()方法不能被模拟,因为它不是虚拟方法。

很明显,我不想测试cookies是否被清除,我只是想在测试中忽略它。

感谢,

格雷格

+0

你见过这样的问题:http://stackoverflow.com/questions/1228179/mocking-httpcontextbase-with-moq – Halvard

+0

谢谢回应,但我已经浏览了链接中的例子,并没有看到我在上面控制器上下文的模拟中没有做过的事情。如果我失去了一些东西,请指点我正确的方向! – Greg

+0

你确定你正在获取模拟的上下文,而不是在该代码部分的HttpContext.Current(例如)?只是想一想什么可能是错的。 – JuhaKangas

回答

14

这个工作对我来说,当我做cookies.Clear()

  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); 
+0

谢谢 - 解决方案只是模拟HttpContextBase而不是你在示例中显示的ControllerContext。还要感谢Halvard的回答,指引我朝着正确的方向前进 – Greg

0

(这是只有一半的答案,但过大的注释字段...)

你的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(),会发生什么情况?其他的一切都是正确的嘲笑吗?当您调试测试时,您能否看到模拟的其余部分与预期一致?如果是的话,我会感到惊讶(但是我之前感到惊讶)。