小编典典

如何在 ASP.Net MVC 中模拟控制器上的请求?

all

我有一个使用 ASP.Net MVC 框架的 C# 控制器

public class HomeController:Controller{
  public ActionResult Index()
    {
      if (Request.IsAjaxRequest())
        { 
          //do some ajaxy stuff
        }
      return View("Index");
    }
}

我得到了一些关于模拟的技巧,并希望用以下和 RhinoMocks 测试代码

var mocks = new MockRepository();
var mockedhttpContext = mocks.DynamicMock<HttpContextBase>();
var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>();
SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest);

var controller = new HomeController();
controller.ControllerContext = new ControllerContext(mockedhttpContext, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);

但是我不断收到此错误:

异常
System.ArgumentNullException:System.ArgumentNullException:值不能为空。参数名称:System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest(HttpRequestBase
request)处的请求

由于Request控制器上的对象没有设置器。我试图通过使用以下答案中的推荐代码来使该测试正常工作。

这使用了 Moq 而不是 RhinoMocks,并且在使用 Moq 时,我使用以下内容进行相同的测试:

var request = new Mock<HttpRequestBase>();
// Not working - IsAjaxRequest() is static extension method and cannot be mocked
// request.Setup(x => x.IsAjaxRequest()).Returns(true /* or false */);
// use this
request.SetupGet(x => x.Headers["X-Requested-With"]).Returns("XMLHttpRequest");

var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new HomeController(Repository, LoginInfoProvider);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);

但得到以下错误:

异常 System.ArgumentException:System.ArgumentException:不可覆盖成员上的无效设置:x =>
x.Headers[“X-Requested-With”] at Moq.Mock.ThrowIfCantOverride(Expression
setup, MethodInfo methodInfo)

同样,似乎我无法设置请求标头。如何在 RhinoMocks 或 Moq 中设置此值?


阅读 73

收藏
2022-08-03

共1个答案

小编典典

使用起订量

var request = new Mock<HttpRequestBase>();
// Not working - IsAjaxRequest() is static extension method and cannot be mocked
// request.Setup(x => x.IsAjaxRequest()).Returns(true /* or false */);
// use this
request.SetupGet(x => x.Headers).Returns(
    new System.Net.WebHeaderCollection {
        {"X-Requested-With", "XMLHttpRequest"}
    });

var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);

var controller = new YourController();
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);

更新:

模拟Request.Headers["X-Requested-With"]Request["X-Requested- With"]代替Request.IsAjaxRequest().

2022-08-03