मैं Moq का उपयोग करके ASP.NET MVC में HttpContext का मज़ाक कैसे उड़ाऊँ?


101
[TestMethod]
public void Home_Message_Display_Unknown_User_when_coockie_does_not_exist()
{
    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    context
        .Setup(c => c.Request)
        .Returns(request.Object);
    HomeController controller = new HomeController();

    controller.HttpContext = context; //Here I am getting an error (read only).
    ...
 }

मेरे बेस कंट्रोलर को इनिशियलाइज़ का ओवरराइड है जो इस रिक्वेस्ट को प्राप्त करता है। मैं इसे पास करने की कोशिश कर रहा हूं लेकिन मैं कुछ ठीक नहीं कर रहा हूं।

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    base.Initialize(requestContext);
}

मैं Moq का उपयोग करके अपने RequestContext और HttpContext के बारे में अधिक जानकारी कहां से प्राप्त कर सकता हूं? मैं कुकीज़ और सामान्य संदर्भ का मजाक उड़ाने की कोशिश कर रहा हूं।

जवाबों:


61

HttpContext केवल-पढ़ने के लिए है, लेकिन यह वास्तव में कंट्रोलरकोटेक्स्ट से लिया गया है, जिसे आप सेट कर सकते हैं।

 controller.ControllerContext = new ControllerContext( context.Object, new RouteData(), controller );

यह मेरे लिए नियंत्रक पर एक नकली HttpContext सेट करने की अनुमति देकर मेरे लिए काम करता है।
जोएल मालोन

39

एक अनुरोध, प्रतिक्रिया बनाएं और उन दोनों को HttpContext पर डालें:

HttpRequest httpRequest = new HttpRequest("", "http://mySomething/", "");
StringWriter stringWriter = new StringWriter();
HttpResponse httpResponse = new HttpResponse(stringWriter);
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);

सवाल यह है कि * बेस क्लासेस, यानी HttpRequestBase, HttpRequest नहीं - के बारे में सुनिश्चित करें कि दोनों को खुद की आवश्यकता क्यों है और इससे भी अधिक कष्टप्रद है कि वे "सील" हैं। LogonUserIdentity को सेट करने का कोई तरीका नहीं :(
क्रिस

अगर वे मेरे संदर्भ को गलत कर रहे हैं, तो यह अभी भी रीमोटिंग के माध्यम से संभव है, इसलिए यह समस्या नहीं होनी चाहिए।
0100110010101

1
@ क्रिसकम्प्टन: अंतिम उपाय के रूप में, हमेशा प्रतिबिंब होता है ;-)
ओलिवर

यह काम करता है जब इसे नियंत्रक से जोड़ते हैं, तो इस तरह से: नियंत्रक ।ControllerContext = new ControllerContext (नया HttpContextWrapper (httpContextMock), नया RouteData (), नियंत्रक);
एंड्रियास वेंडेल

हाँ। आप वास्तव में सेट कर सकते हैं .LogonUserIdentity - _request.Setup (n => n.LogonUserIdentity) .Returns ((WindowsIdentity.GetCurrent));
केविनडेउस

12

धन्यवाद उपयोगकर्ता 0100110010101

इसने मेरे लिए काम किया और यहां मैंने नीचे दिए गए कोड के लिए टेस्टकेस लिखते समय एक मुद्दा था:

 var currentUrl = Request.Url.AbsoluteUri;

और यहाँ लाइनों है जो समस्या को हल किया है

HomeController controller = new HomeController();
//Mock Request.Url.AbsoluteUri 
HttpRequest httpRequest = new HttpRequest("", "http://mySomething", "");
StringWriter stringWriter = new StringWriter();
HttpResponse httpResponse = new HttpResponse(stringWriter);
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);
controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock), new RouteData(), controller);

दूसरों के लिए मददगार हो सकता है।


मैं HttpRequest प्रकार का उपयोग करने के लिए प्रतीत नहीं कर सकता - क्या अब कुछ और है?
विंसेंट बसकेरलो

1
यह उपयोगी नहीं है क्योंकि HttpRequest के सभी क्षेत्र अपरिवर्तनीय हैं
A br

5

यहां बताया गया है कि मैंने एक नकली एप्लिकेशन पथ पास करने के लिए कंट्रोलर कॉन्टेक्स्ट का उपयोग कैसे किया:

[TestClass]
public class ClassTest
{
    private Mock<ControllerContext> mockControllerContext;
    private HomeController sut;

    [TestInitialize]
    public void TestInitialize()
    {
        mockControllerContext = new Mock<ControllerContext>();
        sut = new HomeController();
    }
    [TestCleanup]
    public void TestCleanup()
    {
        sut.Dispose();
        mockControllerContext = null;
    }
    [TestMethod]
    public void Index_Should_Return_Default_View()
    {

        // Expectations
        mockControllerContext.SetupGet(x => x.HttpContext.Request.ApplicationPath)
            .Returns("/foo.com");
        sut.ControllerContext = mockControllerContext.Object;

        // Act
        var failure = sut.Index();

        // Assert
        Assert.IsInstanceOfType(failure, typeof(ViewResult), "Index() did not return expected ViewResult.");
    }
}

1
आपको एक नकली आवेदन पथ पारित करने की आवश्यकता क्यों होगी?
The_law 19

MVC कोड इसे निष्पादित करेगा और यदि यह नहीं है तो एक अशक्त अपवाद को फेंक देगा।
जोशुआ रामिरेज़

5

यहाँ एक उदाहरण है कि आप इसे कैसे सेट कर सकते हैं: Mocking HttpContext HttpRequest और HttpResponse for UnitTests (Moq का उपयोग करके)

उन विस्तार विधियों पर ध्यान दें जो वास्तव में इस नकली कक्षाओं के उपयोग को आसान बनाने में मदद करती हैं:

var mockHttpContext = new API_Moq_HttpContext();

var httpContext = mockHttpContext.httpContext();

httpContext.request_Write("<html><body>".line()); 
httpContext.request_Write("   this is a web page".line());  
httpContext.request_Write("</body></html>"); 

return httpContext.request_Read();

यहां एक उदाहरण दिया गया है कि एक एचक्यूपीएमॉड्यूल की जांच करने के लिए moq का उपयोग करके यूनिट टेस्ट कैसे लिखा जाता है: उम्मीद के मुताबिक काम कर रहा है: HttpModule के लिए यूनिट टेस्ट Moq का उपयोग करके एचटीपीआर असमान

अद्यतन: इस एपीआई को फिर से बनाया गया है


लिंक टूट गए हैं - कृपया अपने उत्तर में कोड शामिल करें
हेड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.