2012-12-06 5 views
8

मैं जीडब्ल्यूटीपी का उपयोग कर रहा हूं, प्रस्तुतकर्ता और दृश्य के बीच ज्ञान को सारणीबद्ध करने के लिए एक अनुबंध परत जोड़ रहा हूं, और मैं परिणामस्वरूप जीडब्ल्यूटीपी के साथ संतुष्ट हूं। मैं अपने प्रस्तुतकर्ताओं को मॉकिटो के साथ परीक्षण कर रहा हूं।एसिंक्रोनस कॉल के साथ जीडब्ल्यूटीपी प्रेजेंटर का परीक्षण

लेकिन जैसे ही समय बीत गया, मुझे पता चला कि इसके परीक्षणों के साथ एक स्वच्छ प्रस्तुति को बनाए रखना मुश्किल था। कुछ सुधार करने के लिए मैंने कुछ सुधार किया है, लेकिन मैं अभी भी संतुष्ट नहीं था।

मुझे इस मामले का दिल होने के लिए निम्नलिखित पाया गया: मेरे प्रस्तुतकर्ताओं को अक्सर असीमित कॉल की आवश्यकता होती है, या आम तौर पर मेरे प्रेजेंटर प्रवाह को जारी रखने के लिए कॉलबैक के साथ ऑब्जेक्ट विधि को कॉल करते हैं (वे आमतौर पर घोंसले होते हैं)।

उदाहरण के लिए:

this.populationManager.populate(new PopulationCallback() 
    { 
    public void onPopulate() 
    { 
     doSomeStufWithTheView(populationManager.get()); 
    } 
    }); 

मेरे परीक्षण में, मैं मज़ाक उड़ाया PopulationManager वस्तु की आबादी() कॉल सत्यापित करने के लिए समाप्त हो गया। फिर doSomeStufWithTheView() विधि पर एक और परीक्षण बनाने के लिए।

लेकिन मुझे पता चला कि यह खराब डिजाइन था: किसी भी बदलाव या रिफैक्टरिंग ने मेरे कई परीक्षण तोड़ने के लिए समाप्त कर दिया, और मुझे दूसरों से शुरू करने के लिए मजबूर किया, भले ही प्रस्तुतकर्ता कार्यक्षमता में बदलाव न हो! प्लस मैंने परीक्षण नहीं किया था कि क्या कॉलबैक प्रभावी रूप से मैं चाहता था।

तो मैं doAnswer विधि mockito उपयोग करने के लिए मेरी प्रस्तोता परीक्षण प्रवाह नहीं टूटते करने की कोशिश की:

doAnswer(new Answer(){ 
    public Object answer(InvocationOnMock invocation) throws Throwable 
    { 
     Object[] args = invocation.getArguments(); 
     ((PopulationCallback)args[0]).onPopulate(); 
     return null; 
    } 
}).when(this.populationManager).populate(any(PopulationCallback.class)); 

मैं कोड यह कम वर्बोज़ (और आंतरिक रूप से कम आर्ग स्थिति के लिए निर्भर) होने के लिए कारक:

doAnswer(new PopulationCallbackAnswer()) 
    .when(this.populationManager).populate(any(PopulationCallback.class)); 

तो populationManager मजाक करते हुए, मैं अभी भी अपने प्रस्तोता के प्रवाह, मूल रूप से इस तरह का परीक्षण कर सकते हैं:

@Test 
public void testSomeStuffAppends() 
{ 
    // Given 
    doAnswer(new PopulationCallbackAnswer()) 
    .when(this.populationManager).populate(any(PopulationCallback.class)); 

    // When 
    this.myPresenter.onReset(); 

    // Then 
    verify(populationManager).populate(any(PopulationCallback.class)); // That was before 
    verify(this.myView).displaySomething(); // Now I can do that. 
} 

मुझे आश्चर्य है कि क्या यह doAnswer विधि का अच्छा उपयोग है, या यदि यह एक कोड गंध है, और एक बेहतर डिजाइन का उपयोग किया जा सकता है?

आमतौर पर, मेरे प्रस्तुतकर्ता केवल अन्य ऑब्जेक्ट (कुछ मध्यस्थ पैटर्न की तरह) का उपयोग करते हैं और दृश्य के साथ बातचीत करते हैं। मेरे पास कोड की कई सौ (~ 400) लाइनों के साथ कुछ प्रस्तुति है।

फिर, क्या यह खराब डिज़ाइन का प्रमाण है, या प्रेजेंटर के लिए वर्बोज़ होना सामान्य है (क्योंकि यह अन्य वस्तुओं का उपयोग कर रहा है)?

क्या किसी ने कुछ परियोजना के बारे में सुना है जो जीडब्ल्यूटीपी का उपयोग करता है और इसके प्रस्तुतकर्ता को स्पष्ट रूप से परीक्षण करता है?

मुझे उम्मीद है कि मैंने व्यापक तरीके से समझाया है।

अग्रिम धन्यवाद।

पीएस: मैं स्टैक ओवरफ़्लो के लिए काफी नया हूं, साथ ही मेरे अंग्रेजी में अभी भी कमी है, अगर मेरे प्रश्न को कुछ सुधारने की ज़रूरत है, तो कृपया मुझे बताएं।

उत्तर

1

आप ArgumentCaptor:
का उपयोग कर सकते हैं blog post और अधिक जानकारी देखें।

+0

यह बिल्कुल सही है !!! +1 – EMM

0

यदि मैं सही ढंग से समझ गया तो आप डिज़ाइन/आर्किटेक्चर के बारे में पूछ रहे हैं।

इसे उत्तर के रूप में नहीं माना जाना चाहिए, यह सिर्फ मेरे विचार है।

अगर मैं पालन किया है कोड:

public void loadEmoticonPacks() { 
    executor.execute(new Runnable() { 
     public void run() { 
      pack = loadFromServer(); 
      savePackForUsageAfter(); 
     } 
    }); 
} 

मैं आमतौर पर प्रबंधक पर भरोसा नहीं है और सिर्फ इतना है कि तरीकों लोड हो रहा है और सहेजकर ठोस काम करता है की जाँच करें। तो यूआई थ्रेड में लंबे संचालन को रोकने के लिए यहां निष्पादक सिर्फ उपकरण है।

अगर मैं की तरह कुछ है:

accountManager.setListener(this); 
.... 
public void onAccountEvent(AccountEvent event) { 
.... 
} 

मैं (कुछ को नष्ट करने पर और सदस्यता वापस ले ली) पहले कि हम घटनाओं के लिए सदस्यता प्राप्त की जाँच करेगा और साथ ही मैं जाँच करेगा कि onAccountEvent उम्मीद परिदृश्यों है।

UPD1। शायद, उदाहरण 1 में, बेहतर loadFromServerAndSave विधि निकालें और जांचें कि इसे यूआई थ्रेड पर निष्पादित नहीं किया गया है और यह भी जांचें कि यह सब कुछ अपेक्षित है।

UPD2। इवेंट प्रोसेसिंग के लिए गुवा बस जैसे ढांचे का उपयोग करना बेहतर है।

0

हम अपने प्रस्तुतकर्ता परीक्षणों में भी इस डूसर पैटर्न का उपयोग कर रहे हैं और आमतौर पर यह ठीक काम करता है। हालांकि एक चेतावनी: यदि आप इसे इस तरह परीक्षण करते हैं तो आप कॉल की असीमित प्रकृति को प्रभावी रूप से हटा रहे हैं, सर्वर कॉल शुरू होने के तुरंत बाद कॉलबैक निष्पादित किया जाता है।

इससे अनदेखा दौड़ की स्थिति हो सकती है। उनको जांचने के लिए, आप इसे दो-चरणीय प्रक्रिया बना सकते हैं: सर्वर को कॉल करते समय, उत्तर विधि केवल कॉलबैक बचाती है। फिर, जब यह आपके परीक्षण में उपयुक्त होता है, तो आप अपने उत्तर पर flush() या onSuccess() की तरह कुछ बार कॉल करते हैं (मैं इसके लिए उपयोगिता वर्ग बनाने का सुझाव दूंगा जिसे अन्य परिस्थितियों में पुन: उपयोग किया जा सकता है), ताकि जब आप नियंत्रित कर सकें परिणाम के लिए कॉलबैक वास्तव में कहा जाता है।

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