MVC4中的单元测试路由/控制器
本文关键字:控制器 路由 单元测试 MVC4 | 更新日期: 2023-09-27 18:19:48
目标:测试给定的url是否返回给定的控制器函数。
在这个过程中,我闯入了路由系统,我不知道如何测试路由(或者,就这一点而言,找到与路由对应的控制器://)。
示例代码,不起作用:
[Test]
public void kick_the_tires()
{
var rc = new RouteCollection();
Infrastructure.RouteRegistry.RegisterRoutes(rc);
// get the route corresponding to name.
var got = rc["name"];
var expected = //What? foo is an internal type that can't be instantiated.
Assert.AreEqual(foo, frob);
}
edit:使用来自Simon的链接博客文章作为存根类。
[TestCase("/", "~/", "Home", "Index")]
[TestCase("/", "api/command", "Other", "command")]
internal void stub_mocker(string apppath, string route, string expected_controller,'
string expected_action)
{
var rc = new RouteCollection();
Infrastructure.RouteRegistry.RegisterRoutes(rc);
var httpmock = new StubHttpContextForRouting(
appPath: apppath,
requestUrl: route);
// this always returns null for everything but the Index case.
var routeData = rc.GetRouteData(httpmock);
var controller = routeData.Values["controller"];
var action = routeData.Values["action"];
Assert.AreEqual(expected_controller, controller);
Assert.AreEqual(expected_action, action);
}
您现在测试的只是路由是否添加到集合中,通过路由名称访问它,而不是预期的路由是否会返回给定的虚拟路径。您需要获取RouteCollection通过HttpContext返回的路由数据。
最好的方法是对HttpContext(或HttpContextBase)使用mock或stub,并调用RouteCollection的GetRouteData(HttpContextBase)方法并检查路由数据。
Brad Wilson的博客中有一个很好的例子:http://bradwilson.typepad.com/blog/2010/07/testing-routing-and-url-generation-in-aspnet-mvc.html
编辑:无法从RouteData本身获取控制器实例。然而,RouteData应该为您提供足够的信息,让您知道哪个控制器将被实例化。例如,如果您在MyProject.Controllers.HomeController
上有一个控制器,其动作为Home
,则在您的测试中(使用xUnit和Moq)这一点应该成立:
// Prepare
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
context.SetupGet(c => c.Request).Returns(request.Object);
context.SetupGet(c => c.Response).Returns(response.Object);
context.SetupGet(c => c.Session).Returns(session.Object);
context.SetupGet(c => c.Server).Returns(server.Object);
request.SetupGet(r => r.HttpMethod).Returns("GET");
request.SetupGet(r => r.PathInfo).Returns(String.Empty);
request.SetupGet(r => r.AppRelativeCurrentExecutionFilePath).Returns("~/Home");
var expectedHandler = typeof (HomeController).GetMethod("Index", Type.EmptyTypes);
var data = RouteTable.Routes.GetRouteData(context.Object);
Assert.NotNull(data);
var handler = (MethodInfo) data.DataTokens["actionMethod"];
Assert.Equal(expectedHandler, handler);
我对MVCContrib的Testhelper 有很好的体验
看看testhelper的这个测试。
省去了很多关于清除HttpContext
等的麻烦
此外,如果您使用的是MVC4,请查看这个Nuget包,它是MVC4的分支。