0

I'm unit testing a simple post:

public HttpResponseMessage<Document> PostDocument(Document document) 
{
    document = repository.Add(document); 

    var response = new HttpResponseMessage<Document>(document, HttpStatusCode.Created); 

    var uri = Url.Route(null, new { id = document.Id }); 

    response.Headers.Location = new Uri(Request.RequestUri, uri); 

    return response; 
}

However, the 'URL' and 'Request' are obviously going to be null.

Is there an alternative to mocking out ControllerContext and HttpContext?

Update:

Changed it to:

 public HttpResponseMessage<Document> PostDocument(Document document,Uri location = null) 
{
    document = repository.Add(document); 

    var response = new HttpResponseMessage<Document>(document, HttpStatusCode.Created);

    if (location == null)
    {
        var uri = Url.Route(null, new { id = document.Id });
        location = new Uri(Request.RequestUri, uri);
    }

    response.Headers.Location = location;

    return response; 
}

Update 2:

This is better:

public HttpResponseMessage<Document> PostDocument(Document document)
{
    var uri = Url.Route(null, new { id = document.Id });
    var location = new Uri(Request.RequestUri, uri);

    return PostDocument(document, location);
}

[NonAction]
public HttpResponseMessage<Document> PostDocument(Document document, Uri location) 
{
    document = repository.Add(document); 

    var response = new HttpResponseMessage<Document>(document, HttpStatusCode.Created);
    response.Headers.Location = location;
    return response; 
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Lee Smith
  • 6,339
  • 6
  • 27
  • 34

3 Answers3

1

Using FakeItEasy I got it to work doing this in the TestInitialize.

this.Controller.ControllerContext = new System.Web.Http.Controllers.HttpControllerContext();
this.Controller.Request = A.Fake<HttpRequestMessage>();
AlignedDev
  • 8,102
  • 9
  • 56
  • 91
1

The Request property should be settable, so you only have to set the ControllerContext (which should have a no-arg constructor so you shouldn't even have to mock).

marcind
  • 52,944
  • 13
  • 125
  • 111
0

Your method might recieve HttpRequestMessage as parameter.

 public HttpResponseMessage<Document> PostDocument(Document document, HttpRequestMessage message)
{

} 

You can take RequestUri from it. In your unit tests you can put test double of HttpRequestMessage object.

Alexander Beletsky
  • 19,453
  • 9
  • 63
  • 86