2012-03-22 163 views
4

我跟着this answer模拟HttpContext,请求,响应和用户,并设置Controller.ControllerContextController.Url当我单元测试我的动作时,为什么Controller.Url为空?

Controller.Url在致电controller.Index()之前绝对不是空。但是,在controller.Index()内部,它是空的。这似乎很奇怪。我错过了什么?

这里是我的测试夹具:

[TestFixture] 
public class ControllerFixtureBase 
{ 
    private Mock<HttpContextBase> _httpContextMock; 
    private RouteCollection _routes; 

    [SetUp] 
    public void SetUp() 
    { 
     var requestMock = new Mock<HttpRequestBase>(); 
     requestMock.SetupGet(x => x.ApplicationPath) 
      .Returns("/"); 
     requestMock.SetupGet(x => x.Url) 
      .Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
     requestMock.SetupGet(x => x.ServerVariables) 
      .Returns(new NameValueCollection()); 

     var responseMock = new Mock<HttpResponseBase>(); 
     responseMock.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())) 
      .Returns((string url) => url); 

     var principalMock = new Mock<IPrincipal>(); 
     principalMock.SetupGet(p => p.Identity) 
      .Returns(new GenericIdentity("testuser")); 
     principalMock.Setup(p => p.IsInRole(ApplicationRoles.DataAdmin)) 
      .Returns(false); 

     _httpContextMock = new Mock<HttpContextBase>(); 
     _httpContextMock.Setup(x => x.User) 
      .Returns(principalMock.Object); 
     _httpContextMock.Setup(x => x.Request) 
      .Returns(requestMock.Object); 
     _httpContextMock.SetupGet(x => x.Response) 
      .Returns(responseMock.Object); 

     _routes = new RouteCollection(); 
     MvcApplication.RegisterRoutes(_routes); 
    } 

    protected void PrepareController(Controller controller) 
    { 
     var requestContext = new RequestContext(_httpContextMock.Object, new RouteData()); 

     controller.ControllerContext = new ControllerContext(requestContext, controller); 
     controller.Url = new UrlHelper(requestContext, _routes); 
    } 

    [Test] 
    public void Index() 
    { 
     HomeController controller = new HomeController(); 
     PrepareController(controller); 

     Assert.That(controller.Url, Is.Not.Null); 
     Assert.That(controller.ViewBag, Is.Not.Null); 

     ViewResult viewResult = controller.Index() as ViewResult; 

     Assert.That(viewResult, Is.Not.Null); 
     Assert.That(viewResult.ViewBag.IndexUrl, Is.EqualTo("/")); 
    } 
} 

这是我的非常简单的动作:

[Authorize] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; 

     // System.NullReferenceException : Object reference not set to an instance of an object. 
     ViewBag.IndexUrl = Url.Action("Index"); 

     return View(); 
    } 
} 

回答

0

看来答案无关与嘲弄。我的MVC和测试项目都是使用MVC 4 beta创建的。我遇到了AuthorizeAttribute的一些奇怪问题,所以我通过创建新项目和移动文件将项目转换为MVC 3。

我必须有一些不匹配的引用,因为当我手动从两个项目中删除所有MVC和Web引用并重新添加它们时,测试通过了。

相关问题