How to mock the Request on Controller in ASP.Net MVC?
Solution 1
Using 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);
UPDATED:
Mock Request.Headers["X-Requested-With"]
or Request["X-Requested-With"]
instead of Request.IsAjaxRequest()
.
Solution 2
For anyone using NSubstitute I was able to modify the above answers and do something like this... (where Details is the Action method name on the controller)
var fakeRequest = Substitute.For<HttpRequestBase>();
var fakeContext = Substitute.For<HttpContextBase>();
fakeRequest.Headers.Returns(new WebHeaderCollection { {"X-Requested-With", "XMLHttpRequest"}});
fakeContext.Request.Returns(fakeRequest);
controller.ControllerContext = new ControllerContext(fakeContext, new RouteData(), controller);
var model = new EntityTypeMaintenanceModel();
var result = controller.Details(model) as PartialViewResult;
Assert.IsNotNull(result);
Assert.AreEqual("EntityType", result.ViewName);
Solution 3
Here is a working solution using RhinoMocks. I've based it on a Moq solution I found at http://thegrayzone.co.uk/blog/2010/03/mocking-request-isajaxrequest/
public static void MakeAjaxRequest(this Controller controller)
{
MockRepository mocks = new MockRepository();
// Create mocks
var mockedhttpContext = mocks.DynamicMock<HttpContextBase>();
var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>();
// Set headers to pretend it's an Ajax request
SetupResult.For(mockedHttpRequest.Headers)
.Return(new WebHeaderCollection() {
{"X-Requested-With", "XMLHttpRequest"}
});
// Tell the mocked context to return the mocked request
SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest);
mocks.ReplayAll();
// Set controllerContext
controller.ControllerContext = new ControllerContext(mockedhttpContext, new RouteData(), controller);
}
Solution 4
Is AjaxRequest is an extension method. So you can do it the following way using Rhino:
protected HttpContextBase BuildHttpContextStub(bool isAjaxRequest)
{
var httpRequestBase = MockRepository.GenerateStub<HttpRequestBase>();
if (isAjaxRequest)
{
httpRequestBase.Stub(r => r["X-Requested-With"]).Return("XMLHttpRequest");
}
var httpContextBase = MockRepository.GenerateStub<HttpContextBase>();
httpContextBase.Stub(c => c.Request).Return(httpRequestBase);
return httpContextBase;
}
// Build controller
....
controller.ControllerContext = new ControllerContext(BuildHttpContextStub(true), new RouteData(), controller);
Solution 5
Looks like you are looking for this,
var requestMock = new Mock<HttpRequestBase>();
requestMock.SetupGet(rq => rq["Age"]).Returns("2001");
Usage in Controller :
public ActionResult Index()
{
var age = Request["Age"]; //This will return 2001
}
Related videos on Youtube
Nissan
Updated on May 17, 2021Comments
-
Nissan about 3 years
I have a controller in C# using the ASP.Net MVC framework
public class HomeController:Controller{ public ActionResult Index() { if (Request.IsAjaxRequest()) { //do some ajaxy stuff } return View("Index"); } }
I got some tips on mocking and was hoping to test the code with the following and 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);
However I keep getting this error:
Exception System.ArgumentNullException: System.ArgumentNullException : Value cannot be null. Parameter name: request at System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest(HttpRequestBase request)
Since the
Request
object on the controller has no setter. I tried to get this test working properly by using recommended code from an answer below.This used Moq instead of RhinoMocks, and in using Moq I use the following for the same test:
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);
but get the following error:
Exception System.ArgumentException: System.ArgumentException : Invalid setup on a non-overridable member: x => x.Headers["X-Requested-With"] at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo)
Again, it seems like I cannot set the request header. How do I set this value, in RhinoMocks or Moq?
-
eu-ge-ne about 15 yearsReplace Request.IsAjaxRequest with Request.IsAjaxRequest()
-
eu-ge-ne about 15 yearsMock Request.Headers["X-Requested-With"] or Request["X-Requested-With"] instead of Request.IsAjaxRequest(). I've updated my question
-
danfromisrael about 14 years
-
-
Nissan about 15 yearsand what would mockedHttpContext need to be mocked? tje RequestContext object it requires needs an HttpContextBase() object in the constructor, and HttpContextBase() has no constructor that accepts zero parameters.
-
Nissan about 15 yearsI get the message "The Type argument for method 'ISetupGetter<T, TProperty>Moq.Mock<T>.SetupGet<Tpropert>.... cannot be infered from uage. Try specifying the type arguments explicitly. What type do I set 'var request=' to though to get this to work?
-
eu-ge-ne about 15 yearsJust updated my answer - not Request.IsAjaxRequest but Request.IsAjaxRequest(). Update your question too
-
Nissan about 15 yearsI tried: var mocks = new MockRepository(); var mockedhttpContext = mocks.DynamicMock<HttpContextBase>(); var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>(); SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest); var controller = new HomeController(Repository, LoginInfoProvider); controller.ControllerContext = new mockedhttpContext, new RouteData(), controller); var result = controller.Index() as ViewResult; However still get the same exception thrown.
-
Nissan about 15 yearsStill generates: Exception System.ArgumentException: System.ArgumentException : Invalid setup on a non-overridable member: x => x.IsAjaxRequest() at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo)
-
eu-ge-ne about 15 yearsThe problem is that IsAjaxRequest() is static extension method and cannot be mocked - I've updated my answer.
-
Nissan about 15 yearsshould be context.SetupGet(x => x.Request).Returns(request.Object); your code above is missing the 's' on Return still Also results in Exception System.ArgumentException: System.ArgumentException : Invalid setup on a non-overridable member: x => x.Headers["X-Requested-With"] at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo) error message
-
Damien about 14 yearsDoes anyone know how I can mock this when I need it to return false? I tried setting ["X-Requested-With"] to null or removing the mock all together but it fails
-
Vdex about 12 yearsYour link doesn't work, but the following seems to work _request.Setup(o => o.Form).Returns(new NameValueCollection());
-
Moojjoo about 9 yearsI am new to Moq, couple of questions: 1. where do you install Moq in your solution? (In other words do you only install in the TEST project) 2. Does Does Moq only come in C# or is there a VB.net Version?
-
LJNielsenDk almost 9 years@Moojjoo 1.: Just on the unit test project. 2.: I don't know. I seen anything about it but I also haven't been looking for it.
-
Emmanuel over 7 yearsA fantastic answer. BTW this solution is only if you want IsAjaxRequest() to return "true". The default behaviour is to return "false". So you don't need to do anything if you want to return "false"; no mocking and no header setting.
-
lastr2d2 over 2 yearsit works with
Microsoft.AspNetCore.Mvc.Core
3.1 as well -
Sasha Bond about 2 yearsAlas, that
HttpRequestBase
is not in .net core 6.0