Asp.net mvc 3 为什么在单元测试我的操作时Controller.Url为空?

Asp.net mvc 3 为什么在单元测试我的操作时Controller.Url为空?,asp.net-mvc-3,nunit,moq,Asp.net Mvc 3,Nunit,Moq,我一直在模仿HttpContext、请求、响应和用户,并设置Controller.ControllerContext和Controller.Url 调用Controller.Index()之前,Controller.Url绝对不为空。但是,在controller.Index()中,它是空的。这似乎很奇怪。我错过了什么 这是我的测试夹具: [TestFixture] public class ControllerFixtureBase { private Mock<HttpConte

我一直在模仿HttpContext、请求、响应和用户,并设置
Controller.ControllerContext
Controller.Url

调用
Controller.Index()
之前,
Controller.Url
绝对不为空。但是,在
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("/"));
    }
}

答案似乎与嘲弄无关。我的MVC和测试项目都是使用MVC4beta创建的。我在AuthorizeAttribute中遇到了一些奇怪的问题,因此我通过创建新项目和移动文件将项目转换为MVC3

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

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