Asp.net-Mvc

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

  • June 9, 2009

我有一個使用 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 中設置此值?

使用起訂量

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().

引用自:https://stackoverflow.com/questions/970198