在单元测试动作时,为什么Controller.Url为null? [英] Why is Controller.Url null when I unit test my action?
问题描述
我已遵循此答案来模拟HttpContext,请求,响应和用户,并设置了Controller.ControllerContext
和
I've followed this answer to mock HttpContext, Request, Response and User and set Controller.ControllerContext
and Controller.Url
.
Controller.Url
绝对不为null.但是,在controller.Index()
中,它为null.看起来很奇怪.我想念什么?
Controller.Url
is most definitely not null before calling controller.Index()
. However, inside controller.Index()
, it is null. It seems very strange. What am I missing?
这是我的测试装置:
[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's 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();
}
}
推荐答案
似乎答案与嘲笑无关.我的MVC和测试项目都是使用MVC 4 Beta创建的.我在AuthorizeAttribute上遇到了一些奇怪的问题,因此我通过创建新项目并移动文件来将项目转换为MVC 3.
It seems the answer has nothing to do with mocking. Both my MVC and test project were creating using MVC 4 beta. I ran into some weird issues with AuthorizeAttribute so I converted the projects to MVC 3 by creating new projects and moving files around.
我一定有一些不匹配的引用,因为当我从两个项目中手动删除所有MVC和Web引用并重新添加它们时,测试就通过了.
I must have had some mismatched references, because when I manually removed all MVC and Web references from both projects and re-added them, the test passed.
这篇关于在单元测试动作时,为什么Controller.Url为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!