ASP.NET MVC: यूनिट परीक्षण नियंत्रक जो UrlHelper का उपयोग करते हैं


170

मेरे नियंत्रकों में से एक, एक जिसे अजाक्स अनुरोध में कहा जा रहा है, वह क्लाइंट पक्ष को एक URL लौटा रहा है ताकि वह पुनर्निर्देशन कर सके। मैं उपयोग कर रहा हूं Url.RouteUrl(..)और मेरी इकाई परीक्षणों के दौरान यह विफल रहता है क्योंकि Controller.Urlपैरामीटर पूर्व-भरा नहीं है।

मैं बहुत कुछ करने की कोशिश की ठूंठ करने का प्रयास कर अन्य लोगों के अलावा, UrlHelper, (जो विफल) मैन्युअल रूप से एक बनाने UrlHelperके लिए एक साथ RequestContextएक टोंटदार है HttpContextBase(जो एक पर विफल रही RouteCollection.GetUrlWithApplicationPathकॉल)।

मैंने Google खोजा है, लेकिन इस विषय पर लगभग कुछ भी नहीं पाया है। क्या मैं Url.RouteUrlअपने नियंत्रक कार्रवाई में अविश्वसनीय रूप से बेवकूफ बना रहा हूं ? क्या कोई आसान तरीका है?

इसे और भी बदतर बनाने के लिए, मैं अपनी इकाई परीक्षण में दिए गए URL का परीक्षण करने में सक्षम होना चाहूंगा - वास्तव में मुझे केवल यह जानने में दिलचस्पी है कि यह सही मार्ग पर पुनर्निर्देशित हो रहा है, लेकिन चूंकि मैं इसके बजाय एक URL वापस कर रहा हूं मार्ग, मैं उस URL को नियंत्रित करना चाहूंगा जो हल किया गया है (जैसे कि एक स्टबड का उपयोग करके RouteCollection) - लेकिन मैं अपना परीक्षण शुरू करने के लिए पास होने के लिए खुश हूं।

जवाबों:


202

यहाँ मेरा एक परीक्षण है (xUnit + Moq) बस इसी तरह के मामले के लिए (कंट्रोलर में Url.RouteUrl का उपयोग करके)

उम्मीद है की यह मदद करेगा:

var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);

var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());

var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier("/post1")).Returns("http://localhost/post1");

var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);

var controller = new LinkbackController(dbF.Object);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
controller.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);

2
कुछ समय के लिए मैं एक समाधान के साथ गया था जहां मैंने उरलहेल्पर को कॉल को अलग कर दिया था ताकि मैं उन्हें बाधित कर सकूं। हालांकि आपके स्निपेट के लिए धन्यवाद, यह मुझे समय की एक बहुत बचत करेगा कि कैसे एक अनुरोध / रिस्पांस / कंट्रोलर कोटेक्स्ट को सही तरीके से मॉक किया जाए।
efdee

इस उत्तर के लिए धन्यवाद @ यूरोप-जीएन, इसने मुझे बहुत मदद की। मैंने UpdateModel द्वारा उपयोग किए गए एक फॉर्मकोलेक्शन पैरामीटर का उपयोग करने के लिए कुछ और moq सेटअप शामिल किए हैं
jebcrum

16
+1 उत्कृष्ट। हालांकि एक टिप: मैं इसे एक मॉकहेलर के रूप में उपयोग करता हूं और प्रतिक्रिया को बदलता हूं। ApplyAppPathModifier के लिए इस पर सेट करें: response.Setup (x => x.ApplyAppPathModifier) ​​(Moq.It.InyAny <String> ()))। रिटर्न ((स्ट्रिंग स्ट्रिंग यूआरएल)। ) => url); यह बदसूरत है, लेकिन मुझे यूआरएल एन्कोडेड फॉर्म में सीरियल की गई वस्तु वापस मिल जाती है, बदले में दिए गए मान को हार्डकोड करने के बजाय।
eduncan911

वह आंशिक रूप से मेरे लिए काम करता है। कोई भी विचार क्यों मुझे नियंत्रक / कार्रवाई के बजाय नियंत्रक मिल जाता है? मेरा परीक्षण विफल हो जाता है क्योंकि वे काफी समान नहीं हैं और फिर भी मैं उसी रूटिंग मूल्यों को पंजीकृत करता हूं। बहुत ही अजीब ...
निक

3
ApplyAppPathModifierभाग UrlHelper के लिए महत्वपूर्ण बिट है
क्रिस एस

37

यूरोप-जीई-एन से एक संशोधित कार्यान्वयन। यह एक एप्लिकेशन में परिभाषित मार्गों के आधार पर एक उत्पन्न लिंक देता है। यूएई-जीई-ने का उदाहरण हमेशा एक निश्चित प्रतिक्रिया लौटाता है। नीचे दिया गया दृष्टिकोण आपको यह परखने की अनुमति देगा कि उरल हेल्पर में सही एक्शन / कंट्रोलर और रूट की जानकारी दी जा रही है - जो आप उरलहेलर को कॉल का परीक्षण कर रहे हैं।

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

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

request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new NameValueCollection());

response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(x => x);

context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);

var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var helper = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);

12

यदि आप HttpContextBase क्लास का मजाक बनाना चाहते हैं तो यह पोस्ट उपयोगी हो सकती है।

http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx


कूल, इससे मुझे मदद मिली, हालाँकि मुझे हेल्पर को उड़ाने से रोकने के लिए FakeHttpContext विधि में कुछ अतिरिक्त कोड जोड़ने पड़े: संदर्भ ।etup (ctx => ctx.Request.ApplicationPath) .Returns ("/ AntiBlowup"); मैंने भी कोड को रीलेक्ट किया है इसलिए यह नए सेटअप () सिंटैक्स का उपयोग करता है। धन्यवाद।
रिचर्ड जूल

2

@ यूआर-जीई-ने-जो ने मुझे बहुत हद तक मदद की, के उत्तर का निर्माण करना:

मेरे पास एक ActionResult था जो एक रीडायरेक्ट के साथ-साथ एक UpdateModel कॉल के साथ एक FormCollection पैरामीटर था। UpdateModel () को काम करने के लिए मुझे इसे अपने Mocked HttpRequestBase में जोड़ना होगा:

FormCollection collection = new FormCollection();
collection["KeyName"] = "KeyValue";

request.Setup(x => x.Form).Returns(collection);
request.Setup(x => x.QueryString).Returns(new NameValueCollection());

यह जांचने के लिए कि पुनर्निर्देशित URL सही था, आप निम्न कार्य कर सकते हैं:

RedirectResult result = controller.ActionName(modelToSubmit, collection) as RedirectResult;
Assert.AreEqual("/Expected/URL", result.Url);

1

http://kbochevski.blogspot.com/2010/06/unit-testing-mvcnet.html चर्चा करता है कि इकाई परीक्षण के साथ सभी परतों को कैसे कवर किया जाए। यह नियंत्रक परीक्षण के लिए राइनो और MVC.Contrib का उपयोग करता है। गूगल पर स्रोत कोड एक बड़ी मदद हो सकती है।

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