views:

279

answers:

3

I am mocking an HttpRequest object using Moq for unit testing in ASP.NET MVC. I need to set one of the ServerVariables (LOGON_USER) in the request. Is this possible? I have tried using the following method, but I get an exception because the ServerVariables collection is non-overridable.

    request.SetupGet(req => req.ServerVariables["LOGON_USER"]).Returns(@"TestUserName");

Is is possible to set a ServerVariable value for testing?

Do I need to pass in a new NameValueCollection rather than trying to set one specific key?

A: 

Ok, figured this one out. I created this method to create the NameValueCollection for the ServerVariables:

private static NameValueCollection CreateServerVariables(string logonUserName)
{
    var collection = new NameValueCollection {{"LOGON_USER", logonUserName}};
    return collection;
}

Then I called it like this in my configuration:

    var request = new Mock<HttpRequestBase>();

    request.SetupGet(req => req.ServerVariables).Returns(CreateServerVariables(userName));
Mark Struzinski
+1  A: 

That's one way to do it. I usually mock these things by changing the rules: I don't want to know about HttpRequest or its relatives in my tests. Instead, I ask: Where can I get the logged on user's name if I were to decide?

And that would be an ICallerContext or whatever better name we can come up with. Then I mock this interface instead.

My controller need a reference to the new dependency:

public class MyController
{
  public MyController(ICallerContext caller) {...}
}

My test need to pass the mocked instance to the controller:

var caller = new Mock<ICallerContext>();
var controller = new MyController(caller.Object);

caller.Setup(c => c.LogonUserName).Returns("TestUserName");

controller.DoTheMagic();

//Assertion(s) goes here...
Thomas Eyde