繁体   English   中英

ASP.NET 5 - MVC 6 - 单元测试使用Url.Action的Controller

[英]ASP.NET 5 - MVC 6 - Unit Test a Controller that uses Url.Action

我有一个MVC6控制器,代码如下:

string link = Url.Action("Profile", "Account");

当我对该控制器进行单元测试时,该行失败并显示错误:

Value cannot be null.
Parameter name: helper

我真的不想模仿Url.Action响应加上我认为我不能,因为它是一个扩展方法(静态方法)。 我想让它像在Web环境中一样运行和返回。

在单元测试中实例化控制器时我需要做什么才能使上面的行按预期执行?

我看到我可以在单元测试中做到这样的事情:

controller.Url = new UrlHelper(new ActionContextAccessor(), new DefaultActionSelector(...));

但我无法弄清楚设置ActionContextAccessor和/或DefaultActionSelector需要什么(需要更多类型,我不知道从哪里获取或如何实例化)。

有没有人这样做过?

谢谢,凯文

当我被困住时,我的妻子总是告诉我只是“离开”一个问题。 她几乎总是对的。

在意识到上面的解决方案无法工作之后(因为它是MVC5),我又看了一眼并意识到controller.Url只是IUrlHelper的一个实例。 我嘲笑这一点, 测试开始工作。 这是我正在做的事情的要点。 这使得测试能够执行。 我确信我可以在模拟中添加更多内容以实际验证它是否按预期运行。

        Mock<IUrlHelper> urlHelperMock = new Mock<IUrlHelper>();
        var controller = new BooksController();
        controller.Url = urlHelperMock.Object;

是的,这很容易LOL。

谢谢,凯文

鉴于:

namespace SampleWebApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            string link = Url.Action("Profile", "Account");
            return View();
        }
    }
}

这个测试似乎运行正常:

using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SampleWebApplication.Controllers;

namespace SampleUnitTestProject
{
    [TestClass]
    public class HomeTests
    {
        private Mock<HttpRequestBase> RequestMock;
        private Mock<HttpResponseBase> ResponseMock;
        private Mock<HttpContextBase> ContextMock;

        [TestInitialize]
        public virtual void Setup()
        {
            this.RequestMock = new Mock<HttpRequestBase>();
            this.ResponseMock = new Mock<HttpResponseBase>();
            this.RequestMock.Setup(m => m.QueryString).Returns(new NameValueCollection());
            this.RequestMock.Setup(m => m.Url).Returns(new Uri("http://www.somedomain.com"));
            this.ContextMock = new Mock<HttpContextBase>();

            this.ContextMock.Setup(m => m.Request).Returns(this.RequestMock.Object);
            this.ContextMock.Setup(m => m.Response).Returns(this.ResponseMock.Object);
        }

        [TestMethod]
        public void Test_Index()
        {
            // Arrange

            using (var controller = new HomeController())
            {
                this.RequestMock.Setup(c => c.ApplicationPath).Returns("/tmp/testpath");
                this.ResponseMock.Setup(c => c.ApplyAppPathModifier(It.IsAny<string>())).Returns("/mynewVirtualPath/");
                var requestContext = new RequestContext(this.ContextMock.Object, new RouteData());
                controller.Url = new UrlHelper(requestContext, new RouteCollection());

                // Act
                var result = controller.Index();

                // Assert
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM