[英]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.