2011-06-14 11 views
14

मुझे एक समस्या है जो वास्तव में मेरे लिए अजीब लगती है। मैं निम्नलिखित सेटअप:EasyMock फैक्ट्री-विधि द्वारा उत्पन्न बीन्स की स्वचालन?

एक इंटरफेस:

package com.example; 

public interface SomeDependency { 
} 

एक वसंत घटक:

package com.example; 

@Component 
public class SomeClass { 
} 

EasyMock द्वारा उत्पन्न एक मज़ाक उड़ाया सेम के साथ एक वसंत परीक्षण config:

<beans ....> 
    <context:component-scan base-package="com.example"/> 

    <bean id="someInterfaceMock" class="org.easymock.EasyMock" factory-method="createMock"> 
     <constructor-arg value="com.example.SomeDependency" /> 
    </bean> 
</beans> 

और एक इकाई परीक्षण:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("/testconfig.xml") 
public class SomeClassTest { 

    @Autowired 
    SomeClass someClass; 

    @Autowired 
    SomeDependency someDependency; 

    @Test 
    public void testSomeClass() throws Exception { 
     assertNotNull(someClass); 
    } 

    @Test 
    public void testSomeDependency() throws Exception { 
     assertNotNull(someDependency); 
    } 
} 

परियोजना संकलित करता है तथा परीक्षण अर्थात बिना किसी समस्या के पास, दोनों SomeClass (एक "असली" वस्तु) की autowiring और SomeDependency (एक नकली EasyMock द्वारा उत्पन्न वस्तु) सफल होते हैं।

हालांकि, अगर मैं SomeClass करने के लिए के कार्यान्वयन को बदलने:

@Component 
public class SomeClass { 

    @Autowired 
    SomeDependency someDependency; 
} 

दोनों परीक्षणों असफल क्योंकि

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.example.SomeDependency] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

तो मेरी प्रश्न हैं:

  1. स्प्रिंग क्यों असफल है पर निर्भरता को स्वत: करने के लिए कुछ क्लास (जब यह कुछ क्लाससेट पर समान निर्भरता को स्वचालित रूप से करने में सफल होता है)?
  2. मैं कैसे परीक्षण पास करने के लिए SomeClassTest या testconfig.xml बदल सकता हूँ?

टिप्पणी: वास्तविकता में वर्ग द्वारा प्रतिनिधित्व किया गया वर्ग कुछ क्लास एक ढांचे का हिस्सा है। नतीजतन, कम से कम उचित समय के भीतर, इसे आसानी से अपडेट नहीं किया जा सकता है।

निर्भरता:

  • स्प्रिंग: 3.0.5.RELEASE
  • EasyMock: 3,0

संपादित करें:

स्प्रिंग 3.2 RC1, सामान्य कारखाने के साथ समस्या के रूप में विधियों और नकली वस्तुओं solved रहा है।

/मैटिस

उत्तर

20

यह जब कारखानों का उपयोग कर autowiring साथ सेम बनाने के लिए वास्तव में बात एक्सएमएल में परिभाषाओं के आदेश लगता है। यदि आप someInterfaceMockcomponent-scan से ऊपर की घोषणा करते हैं तो यह काम करेगा।

कुछ स्पष्टीकरण क्यों: जब वसंत SomeClass को स्वचालित करने की कोशिश करता है तो यह SomeDependency प्रकार के बीन की खोज करता है। इस चरण में someInterfaceMock अभी भी एक कारखाना है इसलिए वसंत फैक्टरी विधि EasyMock.createMock(...) के हस्ताक्षर की जांच करता है जो <T> देता है इसलिए वसंत केवल Object पाता है जो आवश्यक प्रकार नहीं है।

अपने मोजे बनाने के लिए स्प्रिंग के FactoryBean इंटरफ़ेस का उपयोग करने का एक बेहतर तरीका होगा।

यहाँ एक बुनियादी कार्यान्वयन कि काम करना चाहिए है: (! क्रम का कोई प्रभाव नहीं होगा)

public class EasyMockFactoryBean<T> implements FactoryBean<T> { 
    private Class<T> mockedClass; 

    public void setMockedClass(Class mockedClass) { 
     this.mockedClass = mockedClass; 
    } 

    public T getObject() throws Exception { 
     return EasyMock.createMock(mockedClass); 
    } 

    public Class<T> getObjectType() { 
     return mockedClass; 
    } 

    public boolean isSingleton() { 
     return true; 
    } 

} 

यहाँ सेम परिभाषा है:

<bean class="com.example.EasyMockFactoryBean"> 
    <property name="mockedClass" value="com.example.Dependancy"/> 
</bean>  
+0

धन्यवाद! आदेश ने चाल की, लेकिन मुझे लगता है कि मैं EasyMockFactoryBean कार्यान्वयन का उपयोग करूंगा, क्योंकि यह संभावना है कि मुझे बाद में अन्य निर्भरताओं का नकल करना होगा। – matsev

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