2008-10-06 13 views
44

मैंने यहां कुछ उत्तरों को पढ़ा है: परीक्षण दृश्य और नियंत्रक, और मजाक कर रहे हैं, लेकिन मैं अभी भी एएसपी.नेट एमवीसी नियंत्रक का परीक्षण करने का तरीका नहीं समझ सकता जो सत्र मूल्यों को पढ़ता है और सेट करता है (या किसी अन्य संदर्भ आधारित चर ।) मैं अपने परीक्षण विधियों के लिए एक (सत्र) संदर्भ कैसे प्रदान करूं? जवाब मजाक कर रहा है? किसी के पास उदाहरण हैं? मूल रूप से, मैं नियंत्रक विधि को कॉल करने से पहले एक सत्र नकली करना चाहता हूं और नियंत्रक उस सत्र का उपयोग करता हूं। कोई विचार?एएसपी/नेट एमवीसी: टेस्ट कंट्रोलर डब्ल्यू/सत्र? मजाक?

उत्तर

43

नियंत्रक संदर्भ Faking पर स्टीफन वाल्थर पद की जाँच करें:

ASP.NET MVC Tip #12 – Faking the Controller Context

[TestMethod] 
public void TestSessionState() 
{ 
    // Create controller 
    var controller = new HomeController(); 


    // Create fake Controller Context 
    var sessionItems = new SessionStateItemCollection(); 
    sessionItems["item1"] = "wow!"; 
    controller.ControllerContext = new FakeControllerContext(controller, sessionItems); 
    var result = controller.TestSession() as ViewResult; 


    // Assert 
    Assert.AreEqual("wow!", result.ViewData["item1"]); 

    // Assert 
    Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]); 
} 
+3

मुझे इस यूआरएल के लिए खोदना पड़ा, इसलिए यहां यह है: http://stephenwalther.com/blog/archive/2008/07/01/asp-net-mvc-tip-12-faking-the-controller-context। एएसपीएक्स – blu

+3

यह स्पष्ट नहीं हो सकता है, लेकिन FakeControllerContext एक कस्टम क्लास है। आप इसके लिए स्रोत यहां देख सकते हैं: http://stephenwalther.com/Downloads/Tips/Tip12/Tip12.zip –

+0

ऊपर स्रोत स्रोत मृत लगता है .. किसी के पास एक प्रति है? – Flores

12

एएसपी.नेट एमवीसी ढांचा बहुत मजाकिया नहीं है (या बल्कि, सही तरीके से नकली करने के लिए बहुत अधिक सेटअप की आवश्यकता है, और परीक्षण करते समय बहुत अधिक घर्षण का कारण बनता है, आईएमएचओ) इंटरफेस के बजाय अमूर्त बेस वर्गों के उपयोग के कारण। प्रति-अनुरोध और सत्र-आधारित भंडारण के लिए हमारे पास शुभकामनाएं लिखने की अवधारणाएं हैं। हम उन अवशेषों को बहुत हल्का रखते हैं और फिर हमारे नियंत्रक प्रति-अनुरोध या प्रति सत्र भंडारण के लिए उन अवशेषों पर निर्भर करते हैं।

उदाहरण के लिए, यहां हम फॉर्म ऑथ सामान कैसे प्रबंधित करते हैं।

public interface ISecurityContext 
{ 
    bool IsAuthenticated { get; } 
    IIdentity CurrentIdentity { get; } 
    IPrincipal CurrentUser { get; set; } 
} 

की तरह एक ठोस कार्यान्वयन के साथ: हम एक ISecurityContext है

public class SecurityContext : ISecurityContext 
{ 
    private readonly HttpContext _context; 

    public SecurityContext() 
    { 
     _context = HttpContext.Current; 
    } 

    public bool IsAuthenticated 
    { 
     get { return _context.Request.IsAuthenticated; } 
    } 

    public IIdentity CurrentIdentity 
    { 
     get { return _context.User.Identity; } 
    } 

    public IPrincipal CurrentUser 
    { 
     get { return _context.User; } 
     set { _context.User = value; } 
    } 
} 
2

स्कॉट Hanselman MVC के साथ कैसे करने के लिए create a file upload quickapp बारे में एक पोस्ट है और चर्चा करता moking और विशेष रूप से संबोधित करते हैं "कैसे चीजें हैं जो नहीं कर रहे उपहास करने के लिए अनुकूल नहीं है। "

+0

Hanselman ... – Codewerks

5

मुझे काफी आसान होने के लिए मॉकिंग मिली। Moq का उपयोग कर httpContextbase (जिसमें अनुरोध, सत्र और प्रतिक्रिया ऑब्जेक्ट्स शामिल हैं) का मज़ाक उड़ाते हुए एक उदाहरण दिया गया है।

[TestMethod] 
     public void HowTo_CheckSession_With_TennisApp() { 
      var request = new Mock<HttpRequestBase>(); 
      request.Expect(r => r.HttpMethod).Returns("GET");  

      var httpContext = new Mock<HttpContextBase>(); 
      var session = new Mock<HttpSessionStateBase>(); 

      httpContext.Expect(c => c.Request).Returns(request.Object); 
      httpContext.Expect(c => c.Session).Returns(session.Object); 

      session.Expect(c => c.Add("test", "something here"));    

      var playerController = new NewPlayerSignupController(); 
      memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController);   

      session.VerifyAll(); // function is trying to add the desired item to the session in the constructor 
      //TODO: Add Assertions 
     } 

आशा है कि मदद करता है।

+2

वाह, यह बहुत काम सिर्फ एक विधि :) उपहास करने के लिए यह स्पष्ट रूप से "बहुत ज्यादा सेटअप है "गंध, और यह निर्भरता सीम के रूप में इंटरफेस के बजाय अमूर्त आधार वर्गों का उपयोग करने का नतीजा है। – chadmyers

+1

निश्चित रूप से, मैंने कुछ परियोजनाएं देखी हैं जहां उन्होंने सेटअप कोड को "सहायक" वर्ग में रखा है और इसे बार-बार उपयोग किया है। – Korbin

+0

एफवाईआई, यदि आपके परीक्षण को इतनी अधिक सेटअप की आवश्यकता है कि आपको 'सहायक' कक्षा की आवश्यकता है, तो आपको लाइन के नीचे दर्द और घर्षण होने वाला है। – chadmyers

8

MVC आर सी 1 ControllerContext साथ लपेटता HttpContext और एक संपत्ति के रूप में यह उजागर करता है। यह बहुत आसान मजाक कर देता है। Moq के साथ एक सत्र चर उपहास करने के लिए निम्न करें:

var controller = new HomeController(); 
var context = MockRepository.GenerateStub<ControllerContext>(); 
context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue"); 
controller.ControllerContext = context; 

अधिक जानकारी के लिए Scott Gu's post देखें।

0

क्योंकि एचटीपीकॉन्टेक्स्ट स्थिर है, मैं टाइप करने के लिए टाइपेमॉक आइसोलेटर का उपयोग करता हूं, टाइपेमॉक में ASP.NET unit testing के लिए Ivonna नामक एक ऐड-इन कस्टम भी है।

2

मैंने निम्नलिखित समाधान का उपयोग किया - एक नियंत्रक बनाना जो मेरे सभी अन्य नियंत्रकों से प्राप्त होता है। इस प्रकार

public class TestableController : Controller 
{ 

    public new HttpSessionStateBase Session 
    { 
     get 
     { 
      if (session == null) 
      { 
       session = base.Session ?? new CustomSession(); 
      } 
      return session; 
     } 
    } 
    private HttpSessionStateBase session; 

    public class CustomSession : HttpSessionStateBase 
    { 

     private readonly Dictionary<string, object> dictionary; 

     public CustomSession() 
     { 
      dictionary = new Dictionary<string, object>(); 
     } 

     public override object this[string name] 
     { 
      get 
      { 
       if (dictionary.ContainsKey(name)) 
       { 
        return dictionary[name]; 
       } else 
       { 
        return null; 
       } 
      } 
      set 
      { 
       if (!dictionary.ContainsKey(name)) 
       { 
        dictionary.Add(name, value); 
       } 
       else 
       { 
        dictionary[name] = value; 
       } 
      } 
     } 

     //TODO: implement other methods here as needed to forefil the needs of the Session object. the above implementation was fine for my needs. 

    } 

} 

तो कोड का उपयोग करें: बचाव के लिए

public class MyController : TestableController { } 
संबंधित मुद्दे