如何模拟ASP.NET ServerVariables [“HTTP_HOST”]值?

时间:2010-02-23 00:10:33

标签: .net asp.net-mvc mocking moq

我有以下代码,在运行时失败...

var mock = new Mock<ControllerContext>();
mock.SetupGet(x => x.HttpContext.Request
    .ServerVariables["HTTP_HOST"]).Returns(domain);
  

**运行时错误:不可覆盖的设置无效   属性

我的控制器中有一些代码,需要检查用户请求/去过的域。

我不确定如何嘲笑它?任何想法?

PS。我在上面的例子中使用的是Moq framewoke ..所以我不确定这是否是一个问题等等?

2 个答案:

答案 0 :(得分:5)

你不能在NameValueCollection上模拟索引器,因为它不是虚拟的。我要做的是模拟ServerVariables属性,因为那是IS虚拟的。您可以填写自己的NameValueCollection。见下文

这就是我要做的事情:

 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);

答案 1 :(得分:1)

您可以使用界面覆盖HttpContext并在测试中模拟它:

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();
    }
}

然后在控制器代码中使用HttpContextValues而不是ControllerContext.HttpContext。您不必对模拟进行任何组合。