ASP.NET Web API路由单元测试 - 未检测到控制器操作

时间:2014-08-19 14:34:19

标签: unit-testing asp.net-web-api

我正在尝试对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测试时,路由很好。

1 个答案:

答案 0 :(得分:2)

看起来像一个小虫子:))

更改

_actionMappings = actionSelector.GetActionMapping(descriptor)[request.Method.ToString()];

为:

_actionMappings = actionSelector.GetActionMapping(descriptor).
SelectMany(x => x).Where(x => x.SupportedHttpMethods.Contains(request.Method));