2012-08-06 13 views
5

मैं वर्तमान में पहलू का उपयोग कर कुछ निगरानी उपकरण पर काम कर रहा हूं। चूंकि यह उपकरण तकनीकी स्वतंत्र होना चाहिए (जहां तक ​​संभव हो), मैं इंजेक्शन के लिए वसंत का उपयोग नहीं कर रहा हूं। लेकिन मैं चाहता हूं कि मेरे पहलू यूनिट-टेस्ट हों।एक पहलू को नकल करने के लिए कैसे करें

पहलू उदाहरण:

@Aspect 
public class ClassLoadAspect { 
    private Repository repository; 

    public ClassLoadAspect() { 
     repository = OwlApiRepository.getInstance(); 
    } 

    @After("anyStaticInitialization()") 
    public void processStaticInitilization(JoinPoint jp) { 
     Class type = jp.getSourceLocation().getWithinType(); 
     if (type.isInterface()) { 
      repository.storeInterfaceInitialization(type); 
     } else if (type.isEnum()) { 
      repository.storeEnumInitialization(type); 
     } else { 
      repository.storeClassInitialization(type); 
     } 

    } 

    @Pointcut("staticinitialization(*) && !within(cz.cvut.kbss.odra..*)") 
    public void anyStaticInitialization() { 
    } 

    public Repository getRepository() { 
     return repository; 
    } 

    public void setRepository(Repository repository) { 
     this.repository = repository; 
    } 
} 

हालांकि, मैं वास्तव में न कैसे इकाई परीक्षण (भंडार क्षेत्र मज़ाक उड़ाया जाना चाहिए (mockito का उपयोग)) के निर्माण के लिए पता है,, लेकिन मैं नियंत्रण में पहलू निर्माण की जरूरत नहीं है, इसलिए मैं निर्भरता मैन्युअल रूप से सेट नहीं कर सकता। उदाहरण प्राप्त करने के लिए मुझे क्या कहना चाहिए? या कुछ अन्य परिदृश्य है कि पहलू पहलुओं को यूनिट-टेस्ट कैसे करें।

धन्यवाद।

उत्तर

2

आप कहते हैं कि आप नकली वस्तु hacky शुरू करने की अपनी खुद की रास्ता खोजने यहाँ एक स्यूडोकोड है। आप वास्तव में क्या नापसंद करते हैं और आप इसकी कल्पना कैसे करते हैं? मैं केवल अनुमान लगा सकता हूं:

क्या आप इस तथ्य को नापसंद करते हैं कि आप अपने मेटा पहलू में OwlApiRepository.getInstance() पर वैश्विक रूप से कॉल को प्रतिस्थापित करते हैं? एक मेटा (पहलू की इस प्रकार

public privileged aspect ClassLoadTestAspect { 
    static boolean active = true; 

    declare precedence : ClassLoadTestAspect, ClassLoadAspect; 
    pointcut classLoadAspect() : 
     if(active) && 
     withincode(ClassLoadAspect.new()) && 
     call(* OwlApiRepository.getInstance()); 

    Object around() : classLoadAspect() { 
     return new MockRepository(); 
    } 
} 

आप भी देख सकते हैं,: तो फिर आप विशेष रूप से पहलू के निर्माता के लिए नकली वस्तु इंजेक्शन प्रतिबंधित कर सकता है (मैं देशी AspectJ वाक्य रचना का उपयोग कर रहा है क्योंकि मैं POJO एनोटेशन शैली के साथ असहज महसूस करते हैं) -स्टेस्टिंग) पहलू में भी इच्छा पर चालू और बंद करने के लिए एक स्विच है। शायद यह कुछ भी आपको नापसंद था। जैसा कि मैंने कहा, मैं अनुमान लगा रहा हूँ। आपकी प्रतिक्रिया के बाद मैं अधिक विशेष रूप से उत्तर देने में सक्षम हो सकता हूं।

संपादित करें: अपनी चिंताओं का सवाल है, मुझे लगता है कि मैं उन्हें संभव के रूप में संबोधित किया है जहाँ तक:

  • आप एक नकली धारक जरूरत नहीं है।

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

  • मेरा संस्करण विश्व स्तर पर कुछ भी प्रतिस्थापित नहीं करता है, लेकिन एक अच्छा सर्जन की तरह केवल एक जगह पर कम से कम आक्रामक तरीके से कटौती करता है।

  • मैं कई कारणों से बाइट कोड मैनिपुलेशन के बारे में आपकी चिंता को वास्तव में समझ नहीं सकता: आप AspectJ का उपयोग करते हैं, यानी स्वाभाविक रूप से बाइट कोड मैनिपुलेशन (बुनाई)। आप मॉकिटो का उपयोग करते हैं जो रनटाइम पर कक्षाएं बनाता है। मुझे यह भी समझ में नहीं आता कि आप AspectJ में कमी कहां देखते हैं। आपने समझाया नहीं है कि आप कैसे "भाषा के मानक साधन" व्यवहार करना चाहते हैं या परीक्षण के लिए इसे किस इंटरफेस को प्रदान करना चाहिए। यहां तक ​​कि यदि आपके पास भी था, तो मैं आपके लिए अपनी पसंद के भाषा (एजे) और टूल (मॉकिटो) को नहीं बदल सकता।

+0

मुझे अपने समाधान में पसंद नहीं है: स्थिर विधि के वैश्विक प्रतिस्थापन यह मुश्किल परीक्षण करने के लिए बनाता है - मैं भंडार नकली मैन्युअल रूप से रीसेट चाहिए (बजाय एक नया एक स्थापित करने की)। मुझे नकली रिपोजिटरी ऑब्जेक्ट तक पहुंच प्राप्त करने के लिए एक नकली धारक को घुसपैठ करना पड़ा। तीसरी बात यह है कि मैं नकली सेट करने के लिए बाइटकोड से गुस्सा नहीं करना चाहता, मुझे सच में लगता है कि यह भाषा के मानक माध्यमों द्वारा किया जाना है (यदि यह संभव नहीं है, तो यह इम्हो पहलू में कमी दिखाता है डिज़ाइन)। लेकिन कोड से, आपका समाधान हो सकता है (कम से कम धारक की आवश्यकता नहीं है) :-)। – malejpavouk

+0

प्वाइंट लिया गया, बक्षीस तुम्हारा है। धन्यवाद :-) – malejpavouk

+0

शोर के लिए खेद है। मैंने टिप्पणियों को मेरे उत्तर में जोड़ने का फैसला किया है क्योंकि टिप्पणियों के लिए उपलब्ध पात्रों की संख्या बहुत छोटी थी। लेकिन मुझे बक्षीस के साथ देने के लिए वैसे भी धन्यवाद। :) – kriegaex

1

आप अपने परीक्षण विभाजित कर सकते हैं। पहले पहलू के तर्क का परीक्षण करें। यह एक pojo है। हालांकि आप इसे जांच सकते हैं। दूसरा भाग पॉइंटकट का परीक्षण कर रहा है। इस मामले में एक ही बिंदु के साथ एक और सरल पहलू बनाएं (उदा। उन्हें स्थिर के रूप में निकालें)। शायद वहाँ कुछ समर्पित परीक्षण उपकरण हैं, लेकिन मैं किसी भी के बारे में पता नहीं कर रहा हूँ और यह सबसे आसान तरीका है कि मेरे मन

1

मेरे वर्तमान समाधान इस AspectJ आदेश एकमात्र कारखाना विधि ओवरराइड करने के लिए में हैक पेश कर रहा है के लिए आते हैं था

@Aspect 
public class MockingAspect { 

    @Around("call(synchronized static OwlApiRepository *(..))") 
    public OwlApiRepository processGetInstance(ProceedingJoinPoint jp) {  
     System.out.println("getting mock"); 
     return MockHolder.getMock(); 
    } 
} 
0

इन पंक्तियों के साथ कुछ कैसे, मूल रूप से अपने पहलू को बनाए रखना जारी रखें, पहलू के अंदर व्यवहार को दूसरे इंटरफ़ेस में प्रतिनिधि दें, और पहलू को मजाक करने के बजाय अपने परीक्षणों के लिए इंटरफ़ेस का मज़ाक उड़ाएं।

public interface ClassLoadHelper{ 
    void processStaticInitialization(Class<?> clazz); 
} 

public class ClassLoadHelperImpl implements ClassLoadHelper{ 
    private Repository repository; 

    public ClassLoadHelperImpl() { 
     repository = OwlApiRepository.getInstance(); 
    } 

    void processStaticInitialization(Class<?> clazz){ 
     if (type.isInterface()) { 
      this.repository.storeInterfaceInitialization(type); 
     } else if (type.isEnum()) { 
      this.repository.storeEnumInitialization(type); 
     } else { 
      this.repository.storeClassInitialization(type); 
     }   
    } 
} 


@Aspect 
public class ClassLoadAspect { 
    private ClassLoadHelper classLoadHelper; 


    @After("anyStaticInitialization()") 
    public void processStaticInitilization(JoinPoint jp) { 
     Class<?> type = jp.getSourceLocation().getWithinType(); 
     this.classLoadHelper.processStaticInitialization(type); 

    } 

    @Pointcut("staticinitialization(*) && !within(cz.cvut.kbss.odra..*)") 
    public void anyStaticInitialization() { 
    } 

    public ClassLoadHelper getClassLoadHelper() { 
     return classLoadHelper; 
    } 

    public void setClassLoadHelper(ClassLoadHelper classLoadHelper) { 
     this.classLoadHelper = classLoadHelper; 
    } 
} 

अब आप अपने परीक्षण में आप यह कर सकते हैं:

ClassLoadAspect.aspectOf().setClassLoadHelper(mockClassLoadHelper); 
1

क्या आप इकाई परीक्षण सही चाहते हैं? यह कस्टम एप्लिकेशन अपवाद में फेंकने के उद्देश्य से पहलुओं के साथ कस्टम एनोटेशन का परीक्षण करने के लिए एक छोटा इकाई परीक्षण है। (TestNG + Mockito)

public class ResourceApplicationExceptionAspectTest { 
@Mock 
private ProceedingJoinPoint pjp; 
@Mock 
private ResourceApplicationException resourceApplicationException; //annotation definition 

@BeforeMethod 
public void setUp() throws Exception { 
    MockitoAnnotations.initMocks(this); 

} 

@Test(groups ="unit", expectedExceptions = ResourceApplicationException.class) 
public void testWrapExceptionAdvice() throws Throwable { 

    ResourceApplicationExceptionAspect aspect = new ResourceApplicationExceptionAspect(); 

    when(pjp.proceed()).thenThrow(new NullPointerException()); 
    aspect.wrapExceptionAdvice(pjp, resourceApplicationException); 
}