Search code examples
c#.net-corenunitnsubstitute

How to mock Server Variables using NSubstitute


I have the following method to get a user's IP address:

public string GetUserIpAddress(HttpContext context)
{
    var ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

    if (!string.IsNullOrEmpty(ipAddress))
    {
        string[] addresses = ipAddress.Split(',');
        if (addresses.Length != 0)
        {
            return addresses[0];
        }
    }
    return context.Request.ServerVariables["REMOTE_ADDR"];
}

I am trying to write a unit test for this but am struggling to do so (using NSubstitute and NUnit). I have read other articles and so far this is my attempt:

var request = Substitute.For<HttpRequestBase>();
request.ServerVariables.Returns(new System.Collections.Specialized.NameValueCollection
{
    { "HTTP_X_FORWARDED_FOR", "value here" }
});

var httpContext = Substitute.For<HttpContextBase>();
httpContext.Request.Returns(request);

var helper = new UserIpAddressHelper();
var result = helper.GetUserIpAddress(httpContext.ApplicationInstance.Context);

The error is that the result is returning null when I want it to be configured properly with the server variables above.


Solution

  • HttpRequestBase has been created specifically to be testable, because it is abstract and can therefore be overridden by a mocking framework.

    If you want GetUserIpAddress to be testable, have it accept a HttpContextBase instance:

    public string GetUserIpAddress(HttpContextBase context)
    

    If it needs to be called from code that uses HttpContext that can be wrapped:

    HttpContext context;
    var ipAddress = GetUserIpAddress(new HttpContextWrapper(context));