Why is Controller.Url null when I unit test my action?

I followed this answer to mock HttpContext, Request, Response and User and set Controller.ControllerContext and Controller.Url .

Controller.Url most definitely not null before calling controller.Index() . However, inside controller.Index() it is null. It seems very strange. What am I missing?

Here is my test fixture:

 [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("/")); } } 

And here is my very simple action:

 [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(); } } 
+4
source share
1 answer

The answer seems to have nothing to do with ridicule. Both MVC and the test project were created using the beta version of MVC 4. I ran into some strange problems with AuthorizeAttribute, so I converted the projects to MVC 3, creating new projects and moving files.

I must have had some inappropriate links, because when I manually deleted all the MVC and Web links from both projects and re-added them, the test passed.

0
source

Source: https://habr.com/ru/post/1402953/


All Articles