2012-03-22 178 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引用並重新添加它們時,測試通過了。

相關問題