2012-11-12 13 views
10

नकल करने के लिए कैसे मैं वर्तमान में इकाई परीक्षण के लिए Scott Hanselmans HTTP context mock का उपयोग कर रहा था। यह एमवीसी 3 के लिए अच्छा काम करता है और कभी वापस नहीं देखा, मैंने इसे निम्नलिखित कोड के लिए कॉल का परीक्षण करने के लिए उपयोग किया।एमवीसी 4 मॉकिंग HttpContext - DisplayModeProvider

public class PartialViewRenderer : IPartialViewRenderer 
{ 
    public string Render(Controller controller, string viewName, object model) 
    { 
     if (string.IsNullOrEmpty(viewName)) 
      viewName = controller.ControllerContext.RouteData.GetRequiredString("action"); 

     controller.ViewData.Model = model; 

     using (StringWriter sw = new StringWriter()) 
     { 
      ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 
      ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, 
                 controller.ViewData, controller.TempData, sw); 
      viewResult.View.Render(viewContext, sw); 

      return sw.GetStringBuilder().ToString(); 
     } 
    } 
} 

जब मैंने पहली बार अपना ऐप एमवीसी 4 में परिवर्तित कर दिया तो मैं समस्याओं में भाग गया, इसे रनटाइम अपवाद मिल रहे थे। इसलिए मैं के माध्यम से जा रहा है और फिक्सिंग क्या फिक्सिंग, जो मुझ पर Hanselmans MockHelpers निम्न विधियों को बदलने पर उतरा जरूरत की कोशिश की:

public static HttpContextBase FakeHttpContext() 
    { 
     var context = new Mock<HttpContextBase>(); 
     var request = new Mock<HttpRequestBase>(); 
     var response = new Mock<HttpResponseBase>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     var server = new Mock<HttpServerUtilityBase>(); 
     var cookies = new HttpCookieCollection(); 
     var items = new ListDictionary(); 

     request.Setup(r => r.Cookies).Returns(cookies); 
     response.Setup(r => r.Cookies).Returns(cookies); 

     context.Setup(ctx => ctx.Items).Returns(items); 

     context.SetupGet(ctx => ctx.Request).Returns(request.Object); 
     context.SetupGet(ctx => ctx.Response).Returns(response.Object); 
     context.SetupGet(ctx => ctx.Session).Returns(session.Object); 
     context.SetupGet(ctx => ctx.Server).Returns(server.Object); 

     return context.Object; 
    } 

public static void SetFakeControllerContext(this Controller controller, RouteData route) 
    { 
     var httpContext = FakeHttpContext(); 

     ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller); 

     controller.ControllerContext = context; 
    } 
(मैं मूल रूप से, क्योंकि यह "अशक्त" की एक अपवाद बह गया था HttpContext.Items लौटे करने के लिए परिवर्तित) यहाँ

एक बहुत ही सरल NUnit परीक्षण मैं कोशिश करते हैं और जकड़ना क्या परिवर्तन मैं (मैं भी अभी तक इस बात पर ज़ोर में डाल नहीं किया)

[Test] 
    public void test() 
    { 
     _contactsController = _container.Resolve<ContactsController>(); 

     var route = new RouteData(); 

     route.Values.Add("controller", "ContactsController"); 
     route.Values.Add("action", "GetEditContactDetailsDialog"); 

     _contactsController.SetFakeControllerContext(route); 

     var result = _contactsController.GetEditContactDetailsDialog("1"); 
    } 

अब जब मैं इस परीक्षण चलाने http संदर्भ से यह नकली करने के लिए बनाने की जरूरत है के लिए है यह PartialViewRenderer पर बम। ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); पर रेंडर कॉल यहां निम्न स्टैकट्रैक है।

System.Web.WebPages.DisplayModeProvider पर। < .ctor> b__2 (HttpContextBase संदर्भ) System.Web.WebPages.DefaultDisplayMode.CanHandleContext (HttpContextBase httpContext) पर सिस्टम.Web.WebPages.DisplayModeProvider पर । <> c__DisplayClass6.b__5 (IDisplayMode मोड) System.Linq.Enumerable.WhereListIterator 1.MoveNext() at System.Collections.Generic.List 1..ctor पर (IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1 स्रोत) System.Web.WebPages.DisplayModeProvider.GetAvailableDisplayModesForContext (HttpContextBase HttpContext, IDisplayMode currentDisplayMode) पर सिस्टम पर .Web.Mvc.VirtualPathProviderViewEngine.GetPath (ControllerContext controllerContext, String [] स्थानों, String [] areaLocations, स्ट्रिंग locationsPropertyName, स्ट्रिंग नाम, स्ट्रिंग controllerName, स्ट्रिंग cacheKeyPrefix, बूलियन useCache, String [] & searchedLocations)

यह ऐसा लगता है कि मैं वहां नहीं जा सकता और DisplayModeProvider का नकल कर सकता हूं। Per the MVC source Code क्या किसी के पास इसका समाधान है? मैं कहीं भी इसका समाधान ढूंढने में सक्षम हूं।

+0

मुझे डिस्प्लेमोड मॉकिंग के बारे में एक समान समस्या है। मुझे आश्चर्य है कि क्या आपको कोई समाधान मिल सकता है? – Shahin

उत्तर

0

DisplayMode इंटरफ़ेस IDisplayMode लागू करता है, इसलिए आपको इंजेक्ट करने के लिए एक मॉक बनाने में सक्षम होना चाहिए। DisplayModeProvider में SetDisplayMode (संरक्षित) विधि है जिसे आप प्रतिबिंब के माध्यम से आमंत्रित करने में सक्षम हो सकते हैं। यह आप DisplayMode साथ निर्भरता प्राप्त कर सकते हैं का उपयोग करना

var context = new Mock<HttpContextBase>(MockBehavior.Strict); 

:

6

पहले, init MockBehavior.Strict तरह से मजाक उड़ाता है।

http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253810

इसलिए, यह नियत देखें जो उपयोग के लिए Request.Browser पैरामीटर मिलती है:

दूसरा, DisplayMode asp.net MVC के 4 में नई सुविधा है। ब्राउज़र के लिए मॉक जोड़ें:

 var browser = new Mock<HttpBrowserCapabilitiesBase>(MockBehavior.Strict); 
     var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
     var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     var session = new Mock<HttpSessionStateBase>(MockBehavior.Strict); 
     var server = new Mock<HttpServerUtilityBase>(MockBehavior.Strict); 
     var cookies = new HttpCookieCollection(); 
     var items = new ListDictionary(); 

     browser.Setup(b => b.IsMobileDevice).Returns(false); 

     request.Setup(r => r.Cookies).Returns(cookies); 
     request.Setup(r => r.ValidateInput()); 
     request.Setup(r => r.UserAgent).Returns("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"); 
     response.Setup(r => r.Cookies).Returns(cookies); 

     request.Setup(r => r.Browser).Returns(browser.Object); 
     context.Setup(ctx => ctx.Items).Returns(items); 
+0

मुझे अभी तक यह काम करने के लिए नहीं मिला है। अब मुझे एक और त्रुटि मिल रही है, मुझे उम्मीद है कि इस शाम को पता चल जाएगा। – Etch

+0

धन्यवाद, यह कोड एक आकर्षण की तरह काम करता है। – msi

+0

'ViewEngineCollection.FindPartialView()' को कॉल करते समय कुछ याद आ रहा है क्योंकि यह System.Web.Web.Pages.FileExcistenceCache कन्स्ट्रक्टर में 'NullReferenceException' के साथ विफल रहता है। यह उत्तर अन्य परिदृश्यों में काम कर सकता है जैसे कि मैं देख रहा हूं, अभी तक (अभी तक) नहीं। – Manfred

संबंधित मुद्दे