2014-11-05 5 views
5

के साथ नकली निर्भरताओं को इंजेक्ट कैसे करें वर्तमान में मैं यह समझने की कोशिश करता हूं कि @Injectable और @Tested एनोटेशन कैसे काम कर रहे हैं। मैंने पहले से ही कुछ परीक्षण किए हैं और अवधारणा को समझ लिया है, लेकिन मुझे नहीं पता कि मैं वास्तविक दुनिया अनुप्रयोगों में इस कार्यक्षमता का उपयोग कैसे कर सकता हूं। मान लीजिए कि हम एक भाषा अनुवादक वर्ग विकसित कर रहे हैं जो एक वेब सेवा पर निर्भर करता है। वेब सेवा तरीकों एक serparate वर्ग में समाहित हैं:jmockit

// class to test 
public class Translator() { 
    private TranslatorWebService webService; 

    public String translateEnglishToGerman(String word){ 
     webService = new TranslatorWebService(); 
     return webService.performTranslation(word); 
    } 
} 

// dependency 
public class TranslatorWebService { 
    public String performTranslation(String word){ 
    // perform API calls  
    return "German Translation"; 
    } 
} 

अनुवादक वर्ग स्वतंत्र रूप से परीक्षण करने के लिए, हम TranslatorWebService वर्ग नकली करना चाहते हैं। मेरी समझ के अनुसार, परीक्षण वर्ग देखने shoud की तरह:

public class TranslatorTest { 
    @Tested private Translator tested; 
    @Injectable private TranslatorWebService transWebServiceDependency; 

    @Test public void translateEnglishToGerman() { 
     new Expectations() {{ 
      transWebServiceDependency.performTranslation("House"); 
      result = "Haus"; 
     }}; 

     System.out.println(tested.translateEnglishToGerman("House")); 
    } 
} 

जब मैं पहली बार इस परीक्षण का मामला निष्पादित, मैं परिणाम "Haus" उम्मीद है। दूसरी नज़र में मैंने देखा कि लाइन

webService = new TranslatorWebService(); 

हमेशा एक वास्तविक उदाहरण के इंजेक्शन नकली उदाहरण पार कर जाएगी। लेकिन व्यापार तर्क को बदले बिना मैं इस व्यवहार से कैसे बच सकता हूं?

उत्तर

6

अच्छा सवाल। निर्भरता इंजेक्शन के लिए जेमॉकिट (या किसी अन्य मॉकिंग एपीआई) समर्थन के बारे में ध्यान देने योग्य बात यह है कि इसका उपयोग तब किया जाना चाहिए जब परीक्षण के तहत कोड वास्तव में इसकी निर्भरताओं के इंजेक्शन पर निर्भर करता है।

उदाहरण Translator वर्ग TranslatorWebService निर्भरता के लिए इंजेक्शन पर भरोसा करता है; इसके बजाय, यह आंतरिक तत्कालता के माध्यम से सीधे प्राप्त करता है।

public class TranslatorTest { 
    @Tested Translator tested; 
    @Mocked TranslatorWebService transWebServiceDependency; 

    @Test public void translateEnglishToGerman() { 
     new Expectations() {{ 
      transWebServiceDependency.performTranslation("House"); 
      result = "Haus"; 
     }}; 

     String translated = tested.translateEnglishToGerman("House"); 

     assertEquals("Haus", translated); 
    } 
} 
+0

अपने जवाब के लिए धन्यवाद:

तो, यह की तरह एक स्थिति में आप बस निर्भरता नकली कर सकते हैं। मुझे नहीं पता था कि 'मॉक' ऑब्जेक्ट्स इंजेक्शन भी लगाए जाएंगे। प्रलेखन के अनुसार केवल '@ इंजेक्टेबल' ऑब्जेक्ट्स इस सुविधा का समर्थन करते हैं: 'इंजेक्शन के लिए निष्पादित करने के लिए, टेस्ट क्लास में एक या अधिक नकली फ़ील्ड या नकली पैरामीटर भी शामिल होंगे जिन्हें इंजेक्शन योग्य घोषित किया जाना चाहिए। नकली फ़ील्ड/पैरामीटर केवल @ मॉक या @ कैप्चरिंग के साथ एनोटेटेड के लिए नहीं माना जाता है। '(आधिकारिक दस्तावेज़: http://jmockit.github.io/tutorial/BehaviorBasedTesting.html#tested) लेकिन वैसे भी, यह समाधान मेरे लिए काम कर रहा है । आपका बहुत बहुत धन्यवाद! –

+1

'@ मॉक 'ऑब्जेक्ट्स * इंजेक्शन नहीं हैं; उनके वर्ग मजाक कर रहे हैं। –

+1

बस यह इंगित करना चाहता था कि इस मामले में, वेब सेवा "हौस" लौटने की अपेक्षा रखकर और यह कहकर कि परीक्षण विषय "हौस" देता है, हमने वास्तव में एक परीक्षण नहीं किया है। @Mocked का उपयोग करने के बारे में उत्तर सही है, लेकिन मेरे लिए यह सुनिश्चित करना अधिक महत्वपूर्ण लगता है कि हम वास्तव में कुछ उपयोगी परीक्षण प्राप्त करते हैं, इसलिए मैं प्रस्तावित करता हूं कि परीक्षण विषय पुनर्गठित किया जाएगा * या * परीक्षण को केवल सत्यापित करने के लिए बदला जाएगा विषय अपेक्षित पैरामीटर के साथ वेब सेवा पर कॉल करता है। – unigeek

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