2009-03-23 12 views
164
क्लाइंट साइड करने के लिए अपने नियंत्रक कार्यों के

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

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

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

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

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

उत्तर

196

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

आशा इस में मदद करता है के लिए में से एक है HttpContextBase वर्ग नकली करने के लिए।

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

+2

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

+0

उत्तर @ eu-ge-ne के लिए धन्यवाद, इससे मुझे बहुत मदद मिली। मैंने UpdateModel – woopstash

+16

+1 उत्कृष्ट द्वारा उपयोग किए गए फॉर्मकोलेक्शन पैरामीटर का उपयोग करने के लिए कुछ और moq सेटअप शामिल किए हैं। एक टिप हालांकि: मैं एक MockHelper के रूप में उपयोग करने के लिए और इस ApplyAppPathModifier के लिए response.Setup बदलने के लिए: response.Setup (x => x.ApplyAppPathModifier (Moq.It.IsAny ()))।रिटर्न ((स्ट्रिंग यूआरएल) => यूआरएल); यह बदसूरत है, लेकिन मुझे सीरियलाइज्ड ऑब्जेक्ट वापस यूआरएल एन्कोडेड फॉर्म में मिलता है, बदले गए मूल्य को हार्डकोड करने की बजाय। – eduncan911

12

इस पोस्ट उपयोगी अगर आप चाहते हैं हो सकता है:

+0

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

2

द्वारा जवाब बंद बिल्डिंग @ यूरोपीय संघ और जीई-ne जो मुझे एक महान सौदा मदद की:

मैं एक ActionResult कि एक रीडायरेक्ट के रूप में अच्छा प्रदर्शन किया के रूप में एक FormCollection पैरामीटर के साथ एक UpdateModel कॉल था ।

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 चर्चा करने के लिए:

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

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

जांचने के लिए कि रीडायरेक्ट किए गए URL सही था, तो आपको निम्न कर सकते हैं: UpdateModel() काम करने के लिए मैं अपने ठट्ठा HttpRequestBase में जोड़ने के लिए किया था यूनिट परीक्षणों के साथ सभी परतों को कवर करें। यह नियंत्रक परीक्षण के लिए राइनो और एमवीसी। कॉन्ट्रिब का उपयोग करता है। Google पर स्रोत कोड बहुत मददगार हो सकता है।

33

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

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

मेरे लिए बिल्कुल सही प्रतिक्रिया, धन्यवाद स्टीवन! – jhilden