user441521 user441521 - 1 month ago 5
C# Question

C# unit testing API 2 call

I have a web api 2 web service get method. Inside I'm using HttpContext.Current.Request.UserHostAddress. When calling my controller method directly int he unit test this isn't filled in so is errors with null object. So I searched for how to fill this in and found the following which helped with that issue: Add IP address to HttpRequestMessage

However, this needs a server name to send the request to. The problem is that when tests run the VSExpress will need to be running for this API web service, which it won't be when just running the tests. On top of that even if it was it seems it picks a random port to run on so I couldn't hardcode the address like he does in the above link. How can I test my api 2 method given the above issues?

This is the line that blows up when I just test the api method

string ip = HttpContext.Current.Request.UserHostAddress;


[EDIT] Answer

Just so everyone knows here is the solution in code

public class MyController : ApiController
{
private: HttpRequestBase httpRequest;

public MyController()
{
httpRequest = new HttpRequestWrapper(HttpContext.Current.Request)
}

public MyController(HttpRequestBase http)
{
httpRequest = http;
}

public HttpResponseMessage Get()
{
string ip = httpRequest.UserHostAddress;
}
}


I use Moq in the unit test:

Mock<HttpRequestBase> httpRequestMock = new Mock<HttpRequestBase>();

httpRequestMock.Setup(x => x.UserHostAddress).Returns("127.0.0.1");

// then pass httpRequestMock.Object to my controller ctor and good to go

Answer

Replace your references to HttpContext by references to HttpContextBase. When in your code, initialize the HttpContextBase with a HttpContextWrapper instance, which is a the default behavior implementation in a web stack.

However in your test inject a custom HttpContextBase implementation where you implement the methods and behaviors needed by your test only.

As precised in the link:

The HttpContextBase class is an abstract class that contains the same members as the HttpContext class. The HttpContextBase class enables you to create derived classes that are like the HttpContext class, but that you can customize and that work outside the ASP.NET pipeline. When you perform unit testing, you typically use a derived class to implement members with customized behavior that fulfills the scenario you are testing.

Comments