2

I am trying to unit test the following method with Moq, but I am running into issues with the accessibility of manipulating some properties on these classes, and even mocking them up for that matter.

    public string GetClientIpAddress(HttpRequestMessage request)
    {
        if (request.Properties.ContainsKey("MS_HttpContext"))
            return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;

        if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
            return ((RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name]).Address;

        return "IP Address Unavailable";
    }

In order to test, I have created an instance of HttpRequestMessage that I am passing in as a parameter. I am then adding a mock of HttpRequest and HttpContext, like so...

        // Assign 
        var mockHttpRequestBase = new Mock<HttpRequest>();
        mockHttpRequestBase.Setup(m => m.UserHostAddress).Returns("127.0.0.1");

        var mockHttpContext = new Mock<HttpContext>();
        mockHttpContext.Setup(m => m.Request).Returns(mockHttpRequestBase.Object);

        var httpRequestMessage = new HttpRequestMessage();
        httpRequestMessage.Properties.Add(new KeyValuePair<string, object>("MS_HttpContext", mockHttpRequestBase.Object));

        var apiCachedController = new ApiCachedController();

        // Act
        var address = apiCachedController.GetClientIpAddress(httpRequestMessage);

        // Assert
        Assert.AreEqual(address, "127.0.0.1");

EDIT: Sorry for not being clearer on the specific problem(s) I'm having. HttpRequest is unable to be mocked. I get a NotSupportedException that "type to mock must be an interface or an abstract or non-sealed class." I've tried using HttpRequestBase and HttpContextWrapper in place of HttpRequest and HttpContext, respectively, but I receive an InvalidCastException stating, "Unable to cast object of type 'Castle.Proxies.HttpRequestBaseProxy' to type 'System.Web.HttpContextWrapper'."

cdalto
  • 797
  • 1
  • 15
  • 33
  • And what issue are you having? – PatrickSteele Oct 08 '15 at 02:06
  • I apologize for not being clear on that... For starters, HttpRequest is unable to be mocked. I get a NotSupportedException that "type to mock must be an interface or an abstract or non-sealed class." I've tried using HttpRequestBase and HttpContextWrapper in place of HttpRequest and HttpContext, respectively, but I receive an InvalidCastException stating, "Unable to cast object of type 'Castle.Proxies.HttpRequestBaseProxy' to type 'System.Web.HttpContextWrapper'." – cdalto Oct 12 '15 at 14:30

1 Answers1

1

Moq can't create a Mock object from a class itself, you've got to create (and use) an interface in your code and then create a Mock from that.

LWood
  • 417
  • 4
  • 16