কীভাবে এএসপি.নেট এমভিসিতে নিয়ন্ত্রণের উপর অনুরোধের উপহাস করবেন?


171

এএসপি. নেট এমভিসি ফ্রেমওয়ার্কটি ব্যবহার করে আমার সি # তে একটি নিয়ামক রয়েছে

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

আমি উপহাসের বিষয়ে কিছু টিপস পেয়েছি এবং নিম্নলিখিত এবং রিনোমকস সহ কোডটি পরীক্ষা করার আশা করছি

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

তবে আমি এই ত্রুটিটি পেতে থাকি:

ব্যতিক্রম সিস্টেম.আরগমেন্ট নাল এক্সেপশন: সিস্টেম.আরগমেন্ট নাল এক্সসেপশন: মান শূন্য হতে পারে না। প্যারামিটারের নাম: সিস্টেমে অনুরোধ

যেহেতু Requestনিয়ামকের উপর বস্তুর কোনও সেটটার নেই set আমি নীচের উত্তর থেকে প্রস্তাবিত কোড ব্যবহার করে এই পরীক্ষাটি সঠিকভাবে কাজ করার চেষ্টা করেছি।

এটি রাইনোমকসের পরিবর্তে মোখ ব্যবহার করেছে এবং মক ব্যবহারের ক্ষেত্রে আমি একই পরীক্ষার জন্য নিম্নলিখিতটি ব্যবহার করি:

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.ইএইচডারস ["এক্স-রিকুয়েস্টড-উইথ"] মক.মক.ট্রোআইফ্যাক্যান্ট ওভারাইডে (এক্সপ্রেশন সেটআপ, মেথোডিনফো মেথডইনফো)

আবার, মনে হচ্ছে অনুরোধ শিরোনামটি সেট করতে পারছি না। রাইনোমকস বা মোকে আমি কীভাবে এই মানটি সেট করব?


অনুরোধটি প্রতিস্থাপন করুন। অনুরোধের সাথে আইজএজএক্সএক্সএইচএক্সএক্সএক্সএক্সেক্স ()
ইউ-জি-নে

মক রিকুয়েস্ট.ইয়েডাররা ["এক্স-রিকুয়েস্টড-উইথ"]] বা অনুরোধের পরিবর্তে ["এক্স-রিকুয়েস্টড-উইথ"] অনুরোধ করুন। আমি আমার প্রশ্নটি আপডেট করেছি
eu-ge-ne

উত্তর:


211

মোক ব্যবহার :

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


1
আমি বার্তাটি পেয়েছি "পদ্ধতির জন্য প্রকারের আর্গুমেন্ট 'আইসেটআপজেটার <টি, টিপ্রোপার্টি> মক .মক <টি> .সেটআপগেট <Tpropert> .... উয়েজ থেকে জব্দ করা যাবে না the ধরণের আর্গুমেন্টগুলি স্পষ্টভাবে উল্লেখ করার চেষ্টা করুন What আমি কী ধরণের সেট করব? 'var অনুরোধ =' যদিও এটি কাজ করতে
নিসান

সবেমাত্র আমার উত্তরটি আপডেট করেছে - অনুরোধ নয় আইসএজ্যাক্স রিকোয়েস্ট তবে রিকোয়েস্ট.আইএসএজ্যাক্সআরেক্সেস্ট ()। আপনার প্রশ্নটিও আপডেট করুন
eu-ge-ne

এখনও উত্পন্ন: EXCEPTION System.ArgumentException: System.ArgumentException: অবৈধ সেটআপ একটি অ-overridable সদস্য উপর: X => x.IsAjaxRequest () Moq.Mock.ThrowIfCantOverride (এক্সপ্রেশন সেটআপ, MethodInfo methodInfo) এ
নিসান

সমস্যাটি হ'ল ইসএজ্যাক্সরেক্সেস্ট () স্থির এক্সটেনশন পদ্ধতি এবং উপহাস করা যায় না - আমি আমার উত্তর আপডেট করেছি।
eu-ge-ne

কনটেক্সট হওয়া উচিত etসেটআপগেট (x => x.Request) et রিটার্নস (অনুরোধ.অজেক্ট); উপরে আপনার কোডটি রিটার্নে 'এর' অনুপস্থিত রয়েছে এছাড়াও ব্যতিক্রম সিস্টেমের ফলস্বরূপ: সিস্টেম.আরগামেন্ট এক্সেপশন: মোডে একটি অ-ওভারডেবল সদস্যের উপর অবৈধ সেটআপ: x => x.ইহেইডার ["এক্স-অনুরোধযুক্ত সাথে"] .Mock.ThrowIfCantOverride (এক্সপ্রেশন সেটআপ, MethodInfo methodInfo) ত্রুটি বার্তা
নিসান

17

যেহেতু এনএসবিস্টিউট ব্যবহার করছেন আমি তার জন্য উপরের উত্তরগুলি সংশোধন করতে এবং এই জাতীয় কিছু করতে সক্ষম হয়েছি ... (যেখানে বিবরণটি নিয়ামকের উপর ক্রিয়া পদ্ধতির নাম)

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

13

রাইনোমকস ব্যবহার করে এখানে একটি কার্যকরী সমাধান রয়েছে is আমি এটিকে একটি মেক সমাধানের ভিত্তিতে তৈরি করেছি যা আমি 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);
}

5

ইস অ্যাজাক্সেরভেস্ট একটি এক্সটেনশন পদ্ধতি। সুতরাং আপনি গন্ডার ব্যবহার করে নিম্নলিখিত পদ্ধতিতে এটি করতে পারেন:

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

4

দেখে মনে হচ্ছে আপনি এটি সন্ধান করছেন,

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

নিয়ামক ব্যবহার:

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

3

আপনাকে এইচটিটিপি কনটেক্সটবেজকে উপহাস করা এবং এটিকে আপনার কন্ট্রোলার কনটেক্সট সম্পত্তি হিসাবে দেওয়া দরকার:

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

এবং কী উপহাস করা হবে? রিকোয়েস্টকন্টেক্সট অবজেক্টের জন্য এটির কনস্ট্রাক্টরে একটি HTTPContextBase () অবজেক্টের প্রয়োজন, এবং HttpContextBase () এর কোনও নির্মাণকারী নেই যা শূন্য পরামিতি গ্রহণ করে।
নিসান

আমি চেষ্টা করেছি: var mocks = new MockRepository (); var mockedhttpContext = mocks.DynamicMock <HttpContextBase> (); var mockedHttpRequest = mocks.DynamicMock <HttpRequestBase> (); SetupResult.For (mockedhttpContext.Request) .Return (mockedHttpRequest); var কন্ট্রোলার = নতুন হোমকন্ট্রোলার (রিপোজিটরি, লগইনইনফ্রোভাইডার); controller.ControllerContext = নতুন mockedhttpContext, নতুন রুটডেটা (), নিয়ামক); var ফলাফল = নিয়ন্ত্রক। সূচক () ভিউআরসাল্ট হিসাবে; তবে এখনও একই ব্যতিক্রম নিক্ষেপ পেতে।
নিসান

আপনার লিঙ্কটি কাজ করে না, তবে নিম্নলিখিতগুলি _ পুনরুদ্ধার কাজ করে বলে মনে হচ্ছে etসেটআপ (ও => o.Form) et পুনরায় শুরু (নতুন নেমভ্যালিউ কালেকশন ());
Vdex

2

IsAjaxRequest()ইউনিট পরীক্ষার সময় মিথ্যা প্রত্যাবর্তনের জন্য আপনাকে অনুরোধ শিরোনাম সেটআপ করতে হবে এবং নীচের বর্ণিতভাবে আপনার পরীক্ষার পদ্ধতিতে সংগ্রহের মূল্য অনুরোধ করতে হবে:

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

উভয় সেট আপ করার কারণটি নীচে প্রদত্ত ইসএজ্যাক্সরেক্সেস্ট () প্রয়োগের ক্ষেত্রে গোপন রয়েছে:

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

0

নিম্নলিখিত হিসাবে ওয়েব API এর সময় আপনার অনুরোধে একটি HTTPRequestMessage অবজেক্ট যুক্ত করার অন্য উপায় খুঁজে পেয়েছি

[Test]
public void TestMethod()
{
    var controllerContext = new HttpControllerContext();
    var request = new HttpRequestMessage();
    request.Headers.Add("TestHeader", "TestHeader");
    controllerContext.Request = request;
    _controller.ControllerContext = controllerContext;

    var result = _controller.YourAPIMethod();
    //Your assertion
}

0

(পার্টিতে কিছুটা দেরি হলেও আমি অন্য পথে গেলাম তাই ভেবেছি ভাগ করে নিই)

এইচটিটিপি ক্লাসগুলির জন্য বিদ্রূপ তৈরি না করেই এই পরীক্ষার খাঁটি কোড / উপহাসের পথে যেতে আমি একটি আইকন্ট্রোলারহেল্পার প্রয়োগ করেছি যার একটি প্রাথমিক পদ্ধতি রয়েছে যা অনুরোধটিকে প্যারামিটার হিসাবে গ্রহণ করে এবং তারপরে বিশিষ্ট বৈশিষ্ট্যগুলি যেমন আমি চাই:

    public interface IControllerHelper
    {
        void Initialise(HttpRequest request);
        string HostAddress { get; }
    }

    public class ControllerHelper : IControllerHelper
    {
        private HttpRequest _request;
        
        public void Initialise(HttpRequest request)
        {
            _request = request;
        }

        public string HostAddress =>  _request.GetUri().GetLeftPart(UriPartial.Authority);
    }

তারপরে আমার নিয়ামকটিতে আমি পদ্ধতির শুরুতে প্রাথমিক সূচনা বলি:

        _controllerHelper.Initialise(Request);

এবং তারপরে আমার কোডটি কেবল মকেবল নির্ভরশীলতার উপর নির্ভরশীল।

        return Created(new Uri($"{_controllerHelper.HostName}/api/MyEndpoint/{result.id}"), result);

কার্যকরী পরীক্ষার জন্য আমি কেবলমাত্র বিকল্পের জন্য রচনায় আইকন্ট্রোলারহেল্পারকে ওভাররাইড করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.