2012-02-12 17 views
21

मैं इतनी तरह मेरे स्वचालित परीक्षण में कैसल विंडसर उपयोग करने का प्रयास कर रहा हूँ में एक मौजूदा घटक पंजीकरण ओवरराइडकैसल विंडसर 3 में, एक इकाई परीक्षण

  • Setup() समारोह एक बनाता है विंडसर कंटेनर, प्रत्येक घटक की
  • Test समारोह अभिगम विधि IWindsorContainer.Resolve<T> के माध्यम से घटकों, और डिफ़ॉल्ट कार्यान्वयन दर्ज की उनके व्यवहार का परीक्षण करती है
  • विंडसर कंटेनर केसमारोह disposes (और किसी भी बनाई गई घटकों)

उदाहरण के लिए, मैं 15 परीक्षण जो एक IMediaPlayerProxyFactory घटक के निर्माण में घटक जो परोक्ष रूप से परिणाम तक पहुँचता है हो सकता है। SetUp फ़ंक्शन एक अच्छा पर्याप्त कार्यान्वयन IMediaPlayerProxyFactory पंजीकृत करता है, इसलिए मेरे पास 15 परीक्षणों में से प्रत्येक में इसे पंजीकृत करने का रखरखाव बोझ नहीं है।

हालांकि, अब मैं एक परीक्षण Test_MediaPlayerProxyFactoryThrowsException लिख रहा हूं, मेरी प्रणाली की पुष्टि करने से IMediaPlayerProxyFactory घटक से एक त्रुटि ठीक से संभालती है। परीक्षा पद्धति में मैं अपने विशेष नकली कार्यान्वयन बना लिया है, और अब मैं ढांचे को इसकी सुई हैं:

this.WindsorContainer.Register(
           Component.For<IMediaPlayerProxyFactory>() 
              .Instance(mockMediaPlayerProxyFactory) 
          ); 

लेकिन विंडसर एक Castle.MicroKernel.ComponentRegistrationException फेंकता है, संदेश के साथ "वहाँ उस नाम का एक घटक है। "

क्या कोई तरीका है कि मैं mockMediaPlayerProxyFactoryIMediaPlayerProxyFactory के लिए डिफ़ॉल्ट उदाहरण हो सकता हूं, जो पहले से ही पंजीकृत है घटक को छोड़कर?


documentation के अनुसार, महल विंडसर 3 पंजीकरण ओवरराइड के लिए अनुमति देता है, लेकिन मैं केवल एक उदाहरण मिल सकता है:

Container.Register(
    Classes.FromThisAssembly() 
     .BasedOn<IEmptyService>() 
     .WithService.Base() 
     .ConfigureFor<EmptyServiceA>(c => c.IsDefault())); 

ConfigureForBasedOnDescriptor वर्ग की एक विधि है। मेरे मामले में मैं FromDescriptor या BasedOnDescriptor का उपयोग नहीं कर रहा हूं।

उत्तर

55

वहाँ दो चीजें आप एक अधिभावी उदाहरण बनाने के लिए क्या करना है कि कर रहे हैं :

this.WindsorContainer.Register(
          Component.For<IMediaPlayerProxyFactory>() 
             .Instance(mockMediaPlayerProxyFactory) 
             .IsDefault() 
             .Named("OverridingFactory") 
         ); 

मैं इस अधिभावी पैटन उपयोग करने की योजना की वजह से

public static class TestWindsorExtensions 
{ 
    public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class 
    { 
     return componentRegistration 
          .Named(Guid.NewGuid().ToString()) 
          .IsDefault(); 
    } 
} 

अब उदाहरण के लिए सरल किया जा सकता: कई परीक्षणों में, मैं अपने खुद के विस्तार विधि बना लिया है

this.WindsorContainer.Register(
          Component.For<IMediaPlayerProxyFactory>() 
             .Instance(mockMediaPlayerProxyFactory) 
             .OverridesExistingRegistration() 
         ); 


बाद में संपादित

संस्करण 3.1 का परिचय IsFallback तरीका। अगर मैं अपने सभी प्रारंभिक घटकों को IsFallback के साथ पंजीकृत करता हूं, तो कोई भी नया पंजीकरण स्वचालित रूप से इन प्रारंभिक पंजीकरणों को ओवरराइड कर देगा। उस समय कार्यक्षमता उपलब्ध होने पर मैं उस पथ से नीचे जाऊंगा।

https://github.com/castleproject/Windsor/blob/master/docs/whats-new-3.1.md#fallback-components

+0

नामकरण और 'आईएसडीफॉल्ट' विधि का आह्वान वास्तविक कार्यान्वयन पर आवश्यक नहीं है, इसके अलावा, बहुत अच्छा! – bevacqua

+1

उत्तर अद्यतन करने के लिए धन्यवाद। –

1

परीक्षणों में अपने कंटेनर का पुन: उपयोग न करें। इसके बजाय, TearDown() में इसे null पर सेट करें और प्रत्येक वास्तविक परीक्षण के लिए इसे पुन: प्रारंभ करें।

  1. यह एक अद्वितीय नाम दें
  2. कॉल IsDefault विधि

इसलिए उदाहरण पाने के लिए काम करने के लिए:

+0

क्षमा करें, मुझे स्पष्ट नहीं होना चाहिए था। मैं 'TearDown()' में कंटेनर का निपटान करता हूं, और मैं इसे 'SetUp() 'में पुनः प्रारंभ करता हूं। मैं कोशिश करने और इसे और अधिक स्पष्ट करने के लिए अपना परिचय बदल दूंगा। –

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