Question

I'm trying to test routing to my Controller's methods. I've got the following unit test:

[Test]
public void POST_PlaylistItem_Should_route_to_PlaylistItemController_Create_method()
{
    var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/PlaylistItem/");

    var config = new HttpConfiguration();

    WebApiConfig.Register(config);
    var route = Helpers.RouteRequest(config, request);

    route.Controller.Should().Be<PlaylistItemController>();
    route.Action.Should().Be("Create");
}

I need to be able to POST content with the message so that my controller can make a decision between the two following signatures:

[HttpPost]
public PlaylistItemDto Create(PlaylistItemDto playlistItemDto)

[HttpPost]
public IEnumerable<PlaylistItemDto> CreateMultiple(List<PlaylistItemDto> playlistItemDtos)

I was looking through some resources and I found an example for doing it using async + HttpClient, http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client#PostingResource, but I wasn't keen on overcomplicating my example with unfamiliar technology until I had the basics working. Using the HttpClient I wasn't able to easily send a message to the controller / it was acting as if a server isn't running.

Was it helpful?

Solution

Alright, I got it figured out. Note that I haven't converted to Attribute-based routing which is preferable, but this serves as a good starting example:

Goal is to test that these two method signatures don't conflict / confuse Web API:

[HttpPost]
public PlaylistItemDto Create(PlaylistItemDto playlistItemDto)

[HttpPost]
public IEnumerable<PlaylistItemDto> CreateMultiple(List<PlaylistItemDto> playlistItemDtos)

In my WebApiConfig class:

config.Routes.MapHttpRoute(
    name: "Create",
    routeTemplate: "PlaylistItem",
    defaults: new
    {
        controller = "PlaylistItem",
        action = "Create"
    }
);

config.Routes.MapHttpRoute(
    name: "CreateMultiple",
    routeTemplate: "PlaylistItem/CreateMultiple",
    defaults: new
        {
            controller = "PlaylistItem",
            action = "CreateMultiple"
        }
);

This says that anything with just an action name of PlaylistItem will be routed to the Create action. Anything that is PlaylistItem/CreateMultiple will be routed to the CreateMultiple action.

Then, to check to see if this works:

[Test]
public void POST_PlaylistItem_Should_route_to_PlaylistItemController_Create_method()
{ 
    // setups
    var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/PlaylistItem/");

    var config = new HttpConfiguration();

    // act
    WebApiConfig.Register(config);
    var route = Helpers.RouteRequest(config, request);

    // asserts
    route.Controller.Should().Be<PlaylistItemController>();
    route.Action.Should().Be("Create");
}

[Test]
public void POST_CreateMultiple_PlaylistItem_Should_route_to_PlaylistItemController_CreateMultiple_method()
{
    // setups
    var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/PlaylistItem/CreateMultiple");

    var config = new HttpConfiguration();

    // act
    WebApiConfig.Register(config);
    var route = Helpers.RouteRequest(config, request);

    // asserts
    route.Controller.Should().Be<PlaylistItemController>();
    route.Action.Should().Be("CreateMultiple");
}

where RouteRequest comes from Testing route configuration in ASP.NET WebApi

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top