Почему Controller.Url имеет значение null, когда я тестирую свои действия? - PullRequest
4 голосов
/ 22 марта 2012

Я следовал этому ответу , чтобы смоделировать HttpContext, Request, Response и User и установить Controller.ControllerContext и 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();
    }
 }

1 Ответ

0 голосов
/ 22 марта 2012

Кажется, ответ не имеет никакого отношения к насмешкам.И мой MVC, и тестовый проект создавались с использованием бета-версии MVC 4.Я столкнулся с некоторыми странными проблемами с AuthorizeAttribute, поэтому я преобразовал проекты в MVC 3, создав новые проекты и переместив файлы.

У меня, должно быть, были некоторые несовпадающие ссылки, потому что, когда я вручную удалил все ссылки MVC и Web изоба проекта и заново их добавили, тест пройден.

...