This is in the form of a Forum question.
Address: http://stackoverflow.com/questions/970198/how-to-mock-the-request-on-controller-in-asp-net-mvc
How to mock the request on controller in ASP. net mvc?
I have a controller using ASP. NET MVC framework.
Public class homecontroller: controller {
Public actionresult index ()
{
If (request. isajaxrequest ())
{
// Do some ajaxy stuff
}
Return view ("Index ");
}
}
I want to use rhinomocks to test this controller.
VaR mocks = new mockrepository ();
VaR mockedhttpcontext = mocks. dynamicmock VaR mockedhttprequest = mocks. dynamicmock 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 got the following error:
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Exception system. argumentnullexception: system. argumentnullexception: value cannot be null. Parameter Name: request at system. Web. MVC. ajaxrequestextensions. isajaxrequest (httprequestbase request)
Bytes
Although the request object is not initialized in this controller, I try to solve this problem through the following methods.
I used Moq (Mock) instead of rhinomocks to perform the same test.
VaR request = new mock // 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 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 );
However, the following error message is returned:
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
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)
Bytes
This time, it seems that I really cannot reset the header in the request. How can I set the value in the request? Either rhinomocks or Moq can be used. (I am also concerned about this)
#6 level
Using Moq:
VaR request = new mock // 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 Context. setupget (x => X. Request). Returns (request. Object );
VaR controller = new yourcontroller ();
Controller. controllercontext = new controllercontext (context. Object, new routedata (), Controller );
Update:
Replace request. isajaxrequest () with mock request. headers ["X-requested-with"] or request ["X-requested-()
Reply: ============
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. :( 'isetupgetter <t, tproperty> Moq. mock <t>. setupget <tpropert> .... the parameter type in is not clear. Please display the declared parameter type.) How should I write the "Var request =" sentence to solve this error?
Update my problem-request. isajaxrequest () is not request. isajaxrequest. Update your problem.
Still generated: exception system. argumentexception: system. argumentexception: Invalid setup on a non-overridable Member: x => X. isajaxrequest () at Moq. mock. throwifcantoverride (expression setup, methodinfo)
The problem is that the isajaxrequest () is a static extension method that cannot be mocked. I have already changed my answer.
Is this the case? context. setupget (x => X. request ). returns (request. object); the one you used in the returen method is missing the letter 's'; so there will be exception system. argumentexception: system. argumentexception: X in invalid is not reconstructed here X => X. headers ["X-requested-with"]; The result will throw (expression setup, methodinfo) This error message.
#1 Level
You only need to forge an httpcontextbase and introduce it into your controller, just like this:
Controller. controllercontext =
New controllercontext (mockedhttpcontext, new routedata (), Controller );
Now you see how to forge these form conllection, just like your title: mocking the httprequest in ASP. NET MVC
What do mockedhttpcontext need to be counterfeited? It seems that this is httpcontextbase. Httpcontextbase () cannot accept zero parameters.
Why can't I build it indirectly using mocking framework?
I tried it like this: var mocks = new mockrepository (); var mockedhttpcontext = mocks. dynamicmock However, it seems that there are still the same errors.
#0 level
Isn't ajaxrequest an extension method? You can use the mock of rhino to write it like this:
Protected httpcontextbase buildhttpcontextstub (bool isajaxrequest)
{
VaR httprequestbase = mockrepository. generatestub If (isajaxrequest)
{
Httprequestbase. Stub (r => r ["X-requested-with"]). Return ("XMLHttpRequest ");
}
VaR httpcontextbase = mockrepository. generatestub Httpcontextbase. Stub (C => C. Request). Return (httprequestbase );
Return httpcontextbase;
}
// Build Controller
....
Controller. controllercontext = new controllercontext (buildhttpcontextstub (true), new routedata (), Controller );