2012-04-26 23 views
6

पर एकाधिक कस्टम मैचर्स असाइन करता हूं, मैं एक विधि के लिए दो कस्टम मैचर्स का उपयोग करना चाहता हूं। असल में, अगर मैं विधि VALUE_A पास करता हूं, तो मैं इसे RESULT_A वापस लौटना चाहता हूं, और यदि मैं इसे VALUE_B पास करता हूं, तो मैं इसे RESULT_B वापस लौटना चाहता हूं। तो यहाँ एक कोड अंश है:मॉकिटो अजीब तरीके से कार्य करता है जब मैं एक ही विधि

class IsNonEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     //For some reason, this method is called when I assign the IsEmpty matcher to MockHtable.get() 
     //When this happens, the value of the get argument is null, so this method throws an NPE 

     return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    } 
} 

class IsEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     return !(Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key))); 
    } 
}  

[...] 

//This line executes just fine 
Mockito.when(mockHTable.get(Mockito.argThat(new IsNonEmpty()))).thenReturn(dbResult); 

[...] 

//This line calls IsNonEmpty.matches() for some reason. IsNonEmpty.matches() throws an NPE 
Mockito.when(mockHTable.get(Mockito.argThat(new IsEmpty()))).thenReturn(emptyResult); 

जब मैं mockHTable.get() विधि को IsEmpty कस्टम मिलान असाइन करते हैं, यह IsNonEmpty.matches() फ़ंक्शन को कॉल। कोई विचार नहीं कि यह क्यों कर रहा है। तो मैं इस पर IsNonEmpty क्लास को बदलता हूं:

class IsNonEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     //For some reason, this method is called when I assign the IsEmpty matcher. Weird, no? 
     if(get == null) { 
      return false; 
     } 

     return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    } 
} 

और फिर सब कुछ ठीक काम करता है! IsNonEmpty.matches() अभी भी कॉल किया जाता है जब मैं mockHTable.get() फ़ंक्शन पर IsEmpty matcher असाइन करता हूं, लेकिन मेरे matchhers वास्तव में काम करते हैं कि उन्हें कैसे करना चाहिए।

तो सौदा क्या है? ऐसा क्यों होता है? क्या मेरा काम इस विचित्र व्यवहार की भरपाई करने के लिए एक पर्याप्त तरीका है, या क्या मैं गलत कर रहा हूं?

उत्तर

11

कारण IsNonEmpty.matches() स्टबिंग की दूसरी पंक्ति पर कॉल किया जाता है यह है कि Mockito.argThat(new IsEmpty()) शून्य लौटाता है, जिसे mockHTable.get() पर भेज दिया जाता है। यह कॉल देखने के लिए कि क्या यह एक मैच है, इस कॉल को पहले स्टबिंग के खिलाफ जांचना होगा; और इसका मतलब है IsNonEmpty.matches() पर कॉल करना।

मुझे यकीन नहीं है कि यह आपके परीक्षण को विफल क्यों करता है - सभी कोड को देखे बिना बताना मुश्किल है।

लेकिन, when...thenReturn के बजाय doReturn...when का उपयोग करने की गंभीरता से अनुशंसा करते हैं, जब भी आपको एक ही मॉक को एक से अधिक बार स्टब करना होता है। यदि आप ऐसा करते हैं तो आपको इस तरह के मुद्दों का सामना नहीं करना पड़ेगा। वास्तव में, मैं, हालांकि ज्यादातर लोगों when...thenReturn पसंद करते हैं हमेशा when...thenReturn (और इसी तरह doThrow और doAnswer) वरीयता में doReturn...when उपयोग करने के लिए पसंद करते हैं।

को फिर से लिखकर doReturn...when वाक्य रचना के साथ अपने छोटा करते लाइनों में से एक निम्नलिखित की तरह दिखता है। दूसरा समान है।

Mockito.doReturn(dbResult).when(mockHTable).get(Mockito.argThat(new IsNonEmpty())); 

आखिरकार, मॉकिटो विकास टीम की ओर से एक याचिका (जिसमें से मैं सदस्य हूं)। अगर आपको लगता है कि यहां Mockito में एक बग है - और अपने वर्णन से, मुझे लगता है कि अच्छी तरह से हो सकता है - कृपया या तो

  • Mockito मेलिंग समूह को संदेश भेजने के लिए ([email protected]) या
  • मॉकिटो मुद्दों की सूची (http://code.google.com/p/mockito/issues/list) पर कोई समस्या उठाएं।

यह मॉकिटो टीम के लिए उपयोगी है यदि आप वास्तव में एक पूर्ण उदाहरण पोस्ट कर सकते हैं, जो आपको लगता है कि कुंजी लाइनें हैं - कभी-कभी मॉकिटो समस्या का कारण काफी अप्रत्याशित स्थान पर होता है।