21

Closed

Testing ApiController using Url helpers or ObjectContent is too hard

description

Here is the code I am trying to test:
public HttpResponseMessage Post(WriteDocument document)
{
    var response = new HttpResponseMessage(HttpStatusCode.Created);
    var id = Create(reader.Read(document), response);
    response.Headers.Location = new Uri(Url.Link(this.routeName, new { controller = this.ControllerName, id = id }));
    return response;
}

public HttpResponseMessage Put(int id, WriteDocument document)
{
    var response = new HttpResponseMessage();
    var data = this.Update(id, reader.Read(document), response);
    response.Content = GetDocumentContent(writer.Write(new TData[]{data}));
    return response;
}
and here are my tests:
[Fact]
public void WhenPostingShouldSetLocationHeader()
{
    controller.Request.Method = HttpMethod.Post;
    var response = controller.Post(testWriteDocument);
    response.Headers.Location.AbsoluteUri.ShouldEqual("http://localhost/test/1");
}

[Fact]
public void WhenPutShouldReturnDocument()
{
    controller.Request.Method = HttpMethod.Put;
    var response = controller.Put(1,testWriteDocument);
    var value = response.Content.ReadAsAsync<ReadDocument>().Result;
    value.Collection.Href.AbsoluteUri.ShouldEqual("http://test.com/");
}
And here is the davinci work of art to setup my tests.
private void Configure()
{
    var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/test/");
    var config = new HttpConfiguration();
    config.Formatters.Add(new CollectionJsonFormatter());
    var route = config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional });
    var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "test" } });

    controller = new TestController();
    controller.ControllerContext = new HttpControllerContext(config, routeData, request);
    controller.ControllerContext.ControllerDescriptor = new HttpControllerDescriptor(config, "test", typeof(TestController));
    controller.Request = request;
    controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;
    controller.Request.Properties.Add(HttpPropertyKeys.HttpRouteDataKey, routeData);
}
This type of code is not at all intuitive. I would expect to write no more than 2 or 3 lines (ideally 1) of setup to make this work. The scenario itself is something that is quite common.
Closed Feb 18, 2013 at 11:53 PM by HongmeiG

comments

brenkehoe wrote Feb 17, 2013 at 5:34 PM

Completely agree far to much bloat