4

I Have the following test:

[Test]
public void Add_New_Group_Should_Return_StatusCode_Created_And_A_Header_Location_To_The_New_Group()
{
    var newGroup = new GroupData { ID = 1, UserID = 1, Name = "Group 1", Description = "Description 1" };

    var fakeGroupDAL = A.Fake<IGroupDAL>();
    var contactGroupsController = new ContactGroupsController(fakeGroupDAL);
    SetupControllerForTests(contactGroupsController, HttpMethod.Post);

    var response = contactGroupsController.AddGroup(new ContactGroupApiRequest(), newGroup);

    Assert.IsTrue(response.StatusCode == HttpStatusCode.Created, "Should have returned HttpStatusCode.Created");

}

Which calls the following configuration method:

private static void SetupControllerForTests(ApiController controller, HttpMethod httpMethod)
{
    var config = new HttpConfiguration();
    var request = new HttpRequestMessage(httpMethod, "http://localhost/contactgroups");

    var route = config.Routes.MapHttpRoute("ContactGroupsApi", "{controller}/{action}/{request}", new { request = RouteParameter.Optional });
    var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "contactgroups" } });


    controller.ControllerContext = new HttpControllerContext(config, routeData, request);
    controller.Request = request;
    controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;
}

I'm trying to test the following action method:

[HttpPost]
public HttpResponseMessage AddGroup([FromUri]ApiRequest req, [FromBody] GroupData contactGroup)
{

    if(ModelState.IsValid && contactGroup !=null)
    {
        _groupDal.AddGroup(contactGroup);

        contactGroup.Name = HttpUtility.HtmlEncode(String.Format("{0} - {1}", contactGroup.Name, contactGroup.Description));

        var response = new HttpResponseMessage(HttpStatusCode.Created) { Content = new StringContent(contactGroup.Name) };

        var uriString = Url.Link("ContactGroupsApi", new { controller = "contactgroups", action = "Group",  UserId = contactGroup.UserID, GroupId = contactGroup.ID});

        response.Headers.Location = new Uri(uriString);

        return response;
    }

    return Request.CreateResponse(HttpStatusCode.BadRequest);
}

The action method works perfectly well when called normally, but fails under test because the call to Url.Link returns null.

var uriString = Url.Link("ContactGroupsApi", new { controller = "contactgroups", action = "Group",  UserId = contactGroup.UserID, GroupId = contactGroup.ID});  

All this code is based very closely on the following article: Unit test ASP.NET Web Api

I suspect that when running under test there is insufficient route table info. Any idea what I'm doing wrong?

1 Answer 1

14

I fixed my tests by adding the HttpRouteData to the HttpRouteDataKey property of the controller's HttpRequestMessage. Like this:

controller.Request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData;
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks JDM, I would never have thought of that
Although when I look back at the original article. The solution is mentioned in the comments, just never saw it. DOH!!!
Been looking all over for this!
If you upgrade to API 2 and MVC 5 it does not work anymore. The Url object is still null
If you're using Web API 2 or MVC 5, you'll need this: stackoverflow.com/questions/19659257/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.