如何对ASP.NET中WebApiConfig类的MapHttpAttributeRoutes()方法进行单元测试?
如何对ASP.NET中WebApiConfig类的MapHttpAttributeRoutes()方法进行单元测试?
嘿,我来帮你搞定这个单元测试的问题!你要测试的是WebApiConfig里的Register方法,核心就是验证它有没有正确注册属性路由对吧?你已经想到用带路由属性的测试控制器来验证,这个思路完全没问题,只是还需要补全一些关键步骤,让测试能真正跑起来。我给你完善一下代码,同时把每个步骤的作用讲清楚:
完善后的测试代码
首先,我们需要一个小工具类来让测试配置识别我们的私有测试控制器:
// 自定义控制器类型解析器,专门让测试配置能找到我们的私有测试控制器 private class MockControllerTypeResolver : DefaultHttpControllerTypeResolver { private readonly Type[] _targetControllers; public MockControllerTypeResolver(params Type[] controllerTypes) { _targetControllers = controllerTypes; } protected override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver) { return _targetControllers; } } // 你的测试控制器,我给Get方法补了Route属性,这样路由规则更明确 [RoutePrefix("api/TestController")] private class TestController : ApiController { [Route("")] // 匹配RoutePrefix,对应Get请求的完整路由是api/TestController public IHttpActionResult Get() { return Ok(); } } [Fact] public void Register_ShouldRegisterRoutes() { // Arrange:准备测试环境 var config = new HttpConfiguration(); // 替换默认的控制器解析器,不然配置找不到我们的私有测试控制器 config.Services.Replace(typeof(IHttpControllerTypeResolver), new MockControllerTypeResolver(typeof(TestController))); // Act:执行要测试的方法 WebApiConfig.Register(config); // 关键!触发路由的完全初始化,不然路由不会被真正添加到集合里 config.EnsureInitialized(); // Assert:验证结果是否符合预期 // 方式一:检查路由集合里有没有我们预期的路由模板 var hasExpectedRoute = config.Routes.Any(route => { var httpRoute = route as IHttpRoute; return httpRoute?.RouteTemplate == "api/TestController"; }); Assert.True(hasExpectedRoute, "api/TestController 路由未被正确注册"); // 方式二:模拟真实请求,验证路由能正确解析到测试控制器(更严谨) var testRequest = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/TestController"); var matchedRoute = config.Routes.GetRouteData(testRequest); Assert.NotNull(matchedRoute); Assert.Equal("Test", matchedRoute.Values["controller"]); // 控制器名称会自动去掉Controller后缀 }
关键细节解释
- 为什么要自定义控制器解析器? 因为你的
TestController是私有类,ASP.NET Web API默认的控制器扫描逻辑只会找公开的控制器类,所以我们得手动告诉测试配置:“嘿,要算上这个测试控制器哦”。 - 为什么要调用
config.EnsureInitialized()?MapHttpAttributeRoutes()方法只是标记了要注册属性路由,但实际的路由生成和添加操作是延迟执行的,只有调用这个方法才会触发完整的路由初始化流程,不然你在断言时会找不到路由。 - 两种断言方式的区别? 第一种是直接检查路由模板是否存在,比较简单;第二种是模拟真实请求来匹配路由,更贴近实际场景,能验证路由不仅被注册了,还能正常工作。
备注:内容来源于stack exchange,提问作者Brook
相关产品推荐
相关产品推荐

