i have the following code, which fails during runtime...
var mock = new Mock<ControllerContext>();
mock.SetupGet(x => x.HttpContext.Request
.ServerVariables["HTTP_HOST"]).Returns(domain);
** RunTime Error: Invalid setup on non-overridable property
I've got some code in my controller, which needs to check the domain the user has requested开发者_如何学编程/gone to.
I'm not sure how to mock it up? any ideas?
PS. I'm using the Moq framewoke in the above example .. so I'm not sure if that's an issue, etc.?
You can't mock the indexer on a NameValueCollection because it's not virtual. What I would do is mock the ServerVariables property since that IS virtual. You can fill in your own NameValueCollection. See below
Here's what I would do:
var context = new Mock<ControllerContext>();
NameValueCollection variables = new NameValueCollection();
variables.Add("HTTP_HOST", "www.google.com");
context.Setup(c => c.HttpContext.Request.ServerVariables).Returns(variables);
//This next line is just an example of executing the method
var domain = context.Object.HttpContext.Request.ServerVariables["HTTP_HOST"];
Assert.AreEqual("www.google.com", domain);
You can cover HttpContext with interface and mock it in your tests:
interface IHttpContextValues
{
string HttpHost { get; }
}
class HttpContextValues : IHttpContextValues
{
public string HttpHost
{
get { return HttpContext.Current.Request.ServerVariables["HTTP_HOST"]; }
}
}
class BaseController : Controller
{
public IHttpContextValues HttpContextValues;
BaseController()
{
HttpContextValues = new HttpContextValues();
}
}
Then you use HttpContextValues instead of ControllerContext.HttpContext in your controller code. You don't have to make any combinations about mocking.
精彩评论