asp.net mvc करन ASP.Net एमवीसी में नियंत्रक पर अनुरोध का नकल कैसे करें?




पेपर में चीटिंग करने के तरीके (6)

मेरे पास ASP.Net MVC ढांचे का उपयोग कर सी # में नियंत्रक है

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.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest (HttpRequestBase अनुरोध) पर अनुरोध

चूंकि नियंत्रक पर Request ऑब्जेक्ट में कोई सेटटर नहीं है। मैंने नीचे दिए गए उत्तर से अनुशंसित कोड का उपयोग कर इस परीक्षण को ठीक से काम करने की कोशिश की।

इसने RhinoMocks के बजाय Moq का उपयोग किया, और 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);

लेकिन निम्न त्रुटि प्राप्त करें:

अपवाद प्रणाली। ऑर्ग्यूमेंट अपवाद: सिस्टम। ऑर्ग्यूमेंट अपवाद: गैर-अतिसंवेदनशील सदस्य पर अमान्य सेटअप: x => x.Headers ["X-Requested-with"] Moq.Mock.ThrowIfCantOverride (अभिव्यक्ति सेटअप, MethodInfo methodInfo) पर

दोबारा, ऐसा लगता है कि मैं अनुरोध हेडर सेट नहीं कर सकता। मैं RhinoMocks या Moq में, इस मूल्य को कैसे सेट करूं?


आपको HttpContextBase पर नकल करने की आवश्यकता है और इसे अपनी कंट्रोलर कॉन्टेक्स्ट संपत्ति में डाल दें, जैसे कि:

controller.ControllerContext = 
new ControllerContext(mockedHttpContext, new RouteData(), controller);

ऐसा लगता है कि आप इसे ढूंढ रहे हैं,

 var requestMock = new Mock<HttpRequestBase>();
 requestMock.SetupGet(rq => rq["Age"]).Returns("2001");

नियंत्रक में उपयोग:

 public ActionResult Index()
 {
        var age = Request["Age"]; //This will return 2001
 }

क्या AjaxRequest एक विस्तार विधि है। तो आप राइनो का उपयोग करके इसे निम्न तरीके से कर सकते हैं:

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

NSubstitute का उपयोग करने वाले किसी भी व्यक्ति के लिए मैं उपरोक्त उत्तरों को संशोधित करने में सक्षम था और ऐसा कुछ करता हूं ... (जहां विवरण नियंत्रक पर कार्य विधि का नाम है)

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

यूनिट परीक्षण के दौरान IsAjaxRequest() को झूठी वापसी करने के लिए आपको नीचे दिए गए अनुसार अपनी परीक्षण विधि में अनुरोध शीर्षलेखों के साथ ही संग्रह संग्रह मूल्य सेट करने की आवश्यकता है:

_request.SetupGet(x => x.Headers).Returns(new System.Net.WebHeaderCollection { { "X-Requested-With", "NotAjaxRequest" } });
_request.SetupGet(x=>x["X-Requested-With"]).Returns("NotAjaxRequest");

दोनों को स्थापित करने का कारण IsAjaxRequest () के कार्यान्वयन में छिपा हुआ है जो नीचे दिया गया है:

public static bool IsAjaxRequest(this HttpRequestBase request)<br/>
{ 
    if (request == null)
    {
        throw new ArgumentNullException("request");
    }
    return ((request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest")));
}

यह अनुरोध संग्रह और शीर्षलेख दोनों का उपयोग करता है इसलिए हमें हेडर और अनुरोध संग्रह दोनों के लिए सेटअप बनाने की आवश्यकता है।

यह अजाक्स अनुरोध नहीं होने पर झूठी वापसी का अनुरोध करेगा। इसे सच करने के लिए आप निम्न कार्य कर सकते हैं:

_httpContext.SetupGet(x => x.Request["X-Requested-With"]).Returns("XMLHttpRequest");

RhinoMocks का उपयोग कर एक कामकाजी समाधान यहाँ है। मैंने इसे एक Moq समाधान पर आधारित किया है जिसे मैंने 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);
}






moq