我正在尝试对ASP.NET Web API 2控制器中的路由进行单元测试。我严格遵循新发布的书ASP.NET Web Api 2 Recipes中的11-6配方。这是我的控制器:
[RoutePrefix("api/account")]
public class AccountController : ApiController
{
private AccountService _accountService;
public AccountController(AccountService service)
{
_accountService = service;
}
[Route("{id}")]
public IHttpActionResult Get(string id)
{
return Ok(_accountService.Get(id));
}
[Route("all")]
public IHttpActionResult GetAll()
{
return Ok(_accountService.GetAll());
}
}
这是我的单元测试(xunit):
public class AccountRoutingTest
{
readonly HttpConfiguration _config;
public AccountRoutingTest()
{
_config = new HttpConfiguration();
_config.MapHttpAttributeRoutes();
_config.EnsureInitialized();
}
[Theory]
[InlineData("http://acme.com/api/account/john")]
public void GetRoutingIsOk(string url)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
var routeTester = new RouteContext(_config, request);
Assert.Equal(typeof(AccountController), routeTester.ControllerType);
Assert.True(routeTester.VerifyMatchedAction(Reflection.GetMethodInfo((AccountController c) => c.Get(""))));
}
[Theory]
[InlineData("http://acme.com/api/account/all")]
public void GetAllRoutingIsOk(string url)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
var routeTester = new RouteContext(_config, request);
Assert.Equal(typeof(AccountController), routeTester.ControllerType);
Assert.True(routeTester.VerifyMatchedAction(Reflection.GetMethodInfo((AccountController c) => c.GetAll())));
}
}
第一次单元测试通过,但第二次单元测试失败。我已将问题隔离在以下行的RouteContext帮助器类中,其中GetActionMapping方法仅检测Get(id)操作 - 而不是GetAll():
_actionMappings = actionSelector.GetActionMapping(descriptor)[request.Method.ToString()];
我尝试使用[HttpGet]属性显式修饰GetAll()操作方法,并从属性路由切换到集中路由 - 但没有成功。我的想法已经不多了。 GetActionMapping方法为什么没有检测到GetAll()操作以及除Get(id)操作之外的所有其他操作?
从浏览器或Fiddler测试时,路由很好。
答案 0 :(得分:2)
看起来像一个小虫子:))
更改
_actionMappings = actionSelector.GetActionMapping(descriptor)[request.Method.ToString()];
为:
_actionMappings = actionSelector.GetActionMapping(descriptor).
SelectMany(x => x).Where(x => x.SupportedHttpMethods.Contains(request.Method));