2012-01-31 14 views
13

मेरे पास Foo कक्षा है जो SUT है और Bar कक्षा है, जो इसके सहयोगी है। Foo पर Bar पर "expectedList" तर्क के साथ कॉल करता है। फिर, Foo इस List पर कुछ और तत्व जोड़ देगा ताकि run() पर कॉल करने के समय उसका राज्य अलग-अलग होगा। मेरा टेस्ट केस यहाँ है।विधि कॉल के समय Mockito उनके मानों के आधार पर पैरामीटर सत्यापित कर सकते हैं?

@Test 
public void testFoo() { 
    Bar collaborator = spy(new Bar()); 
    Foo sut = new Foo(collaborator); 
    verify(collaborator).run(expectedList); 
} 

ध्यान दें कि सहयोगी वास्तव में एक नकली बजाए एक जासूसी वस्तु है। यह टेस्ट केस विफल हो जाएगा क्योंकि run() को expectedList के बराबर तर्क के साथ बुलाया गया था, इसलिए इसे संशोधित किया गया था और इसका वर्तमान मान अब expectedList के बराबर नहीं है। हालांकि, इस तरह से काम करना है, इसलिए मैं सोच रहा हूं कि मॉकिटो को पैरामीटर के स्नैपशॉट को स्टोर करने का कोई तरीका है जब किसी विधि को बुलाया जाता है और इन मूल्यों के आधार पर उन्हें सबसे हाल के मानों के आधार पर सत्यापित किया जाता है।

उत्तर

11

जब विधि कहा जाता है तर्क के मान की जाँच करने के लिए एक Answer का प्रयोग करें। यदि आप मान गलत हैं, तो आप Answer के भीतर AssertionError फेंक सकते हैं या आप मूल्य को स्टोर कर सकते हैं और अंत में अपना दावा कर सकते हैं।

+0

हाँ डेविड सही है। मॉकिटो के एपीआई को तैयार करने के तरीके के कारण एक ही तर्क संदर्भ के साथ एकाधिक कॉल को सत्यापित करना संभव नहीं है। EasyMock ऐसा कर सकता है क्योंकि उत्पादन कोड चलाने से पहले इसकी उम्मीद चरण है। वैसे भी 'उत्तर' के बजाय मैं 'ArgurmentCaptor' का उपयोग करता हूं और उस सूची की अंतिम स्थिति पर एक या अधिक दावे लिखता हूं, यानी फेस्ट-एसेर्ट' assertThat (captor.getValue()) के साथ। ("ए", "बी ")। कंटेनेंस (" टी "," यू ");' – Brice

+0

@ ब्रिस - यह माइकल विल्स के दृष्टिकोण से अलग कैसे काम करेगा? –

+0

यह नहीं है। यह परीक्षण उद्देश्य प्राप्त करने का एक अलग तरीका है। क्योंकि ज्यादातर समय आपको वास्तव में मध्यवर्ती तर्कों की जांच करने की आवश्यकता नहीं होती है, लेकिन केवल कुछ इंटरैक्शन और अंतिम परिणाम हुआ।हालांकि मुझे यह कहना होगा कि टॉम की विशिष्ट आवश्यकता थी तो सहमत हो गया कि इससे उसकी मदद नहीं होगी, लेकिन फिर इस मामले में मैं अपने उत्पादन कोड में परिवर्तनीय वस्तुओं से बचूंगा। ऐसा लगता है कि दो सहयोगियों और संदेशों के बीच मैसेजिंग हमेशा अपरिवर्तनीय होना चाहिए। – Brice

0

आप पर किसी ऑब्जेक्ट पर verify() पर कॉल नहीं कर सकते हैं। क्या यही आपका मतलब है?

Bar collaborator = mock(Bar.class); 
Foo sut = spy(new Foo(collaborator)); 
verify(collaborator).run(expectedList); 
+0

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

-1

आप जब यह चलाया गया था की उम्मीद सूची का मान प्राप्त करने के लिए तर्क पर कब्जा का उपयोग कर क्यों कोशिश मत करो और फिर आप यह तुलना कर सकते हैं।

ArgumentCaptor<List> listCaptor = ArgumentCaptor.forClass(List.class); 

verify(collaborator).run(listCaptor.capture()); 

assertEquals(expectedList, argument.getValue()); 
+6

यदि आपकी संशोधित सूची एक ही उदाहरण है, तो argument.getValue() 'अपेक्षित सूची' उदाहरण वापस करेगा, प्रतिलिपि नहीं, इसलिए यह अनिवार्य रूप से वही है जैसा वह कर रहा है, है ना? – jhericks

+0

@ माइकल वाइल्स धन्यवाद, लेकिन जैसा कि जेरिकिक्स ने उल्लेख किया है, ArgumentCaptor मूल सूची उदाहरण को कैप्चर करता है। –

+0

क्षमा करें, माइकल, मैंने आपका जवाब घटा दिया क्योंकि आपके समाधान में ओपी के परीक्षण के समान ही समस्या है, जैसा कि जेरिकिक्स द्वारा समझाया गया है। –

1

The answer of Dawood ibn Kareem मेरे लिए काम किया है, लेकिन मैं एक उदाहरण कमी रह गई थी, यह भी मैं Kotlin और Mockito-Kotlin, उपयोग करती हैं इसलिए मेरी समाधान इस तरह है:

class Foo(var mutable: String) 

interface Bar { 
    fun run(foo: Foo) 
} 

@Test fun `validate mutable parameter at invocation`() { 
    val bar = mock<Bar>() 

    var valueAtInvocation: String? = null 
    whenever(bar.run(any())).then { 
     val foo = it.arguments.first() as Foo 
     valueAtInvocation = foo.mutable // Store mutable value as it was at the invocation 
     Unit // The answer 
    } 

    val foo = Foo(mutable = "first") 
    bar.run(foo) 
    valueAtInvocation isEqualTo "first" 

    foo.mutable = "second" 
    bar.run(foo) 
    valueAtInvocation isEqualTo "second" 
} 

valueAtInvocation के अंतिम मंगलाचरण पर परिवर्तनशील संपत्ति foo.mutable के मूल्य का प्रतिनिधित्व करेंगे bar.run(foo)then {} ब्लॉक के भीतर दावा करना भी संभव होना चाहिए।

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