2015-02-03 11 views
37

मॉकिटो - मैं समझता हूं कि एक जासूस किसी ऑब्जेक्ट पर असली विधियों को कॉल करता है, जबकि एक मॉक डबल ऑब्जेक्ट पर विधियों को कॉल करता है। कोड गंध होने तक भी जासूसों से बचा जाना चाहिए। हालांकि, जासूस कैसे काम करते हैं और मुझे वास्तव में उनका उपयोग कब करना चाहिए? वे मोजे से अलग कैसे हैं?मॉकिटो - जासूस बनाम नकली

+1

[मॉकिटो मॉक बनाम जासूसी] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/15052984/mockito-mock-vs-spy) – rds

+0

[मॉकिंग बनाम मजाकिंग फ्रेमिंग में जासूसी बनाम जासूसी] का संभावित डुप्लिकेट (http: //stackoverflow.com/questions/12827580/mocking-vs-spying-in-mocking-frameworks) – PenguinEngineer

उत्तर

6

शुरू करने के लिए सबसे अच्छी जगह शायद the docs for mockito है।

एक सामान्य नोट पर मॉकिटो मॉक आपको स्टब्स बनाने की अनुमति देता है।

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

यदि आप जिस तर्क का परीक्षण कर रहे हैं उसे डेटाबेस कनेक्शन की परवाह नहीं है तो आप उस विधि को एक स्टब के साथ प्रतिस्थापित कर सकते हैं जो हार्ड कोडेड मान देता है।

मॉकिटो जासूस आपको यह जांचने देता है कि कोई विधि अन्य विधियों को कॉल करती है या नहीं। परीक्षण के तहत विरासत कोड प्राप्त करने का प्रयास करते समय यह बहुत उपयोगी हो सकता है।

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

35

तकनीकी रूप से दोनों "मोक्स" और "जासूस" बोलते हुए एक विशेष प्रकार का "परीक्षण युगल" होता है।

दुर्भाग्यवश दुर्भाग्य से भेद को अजीब बना रहा है।

mockito में एक नकली अन्य मजाक चौखटे में एक सामान्य नकली (हैं, अर्थात, विशिष्ट मान विधि कॉल से बाहर लौटने आप आमंत्रण ठूंठ के लिए अनुमति देता है)।

मॉकिटो में एक जासूस अन्य आलिंगन ढांचे में आंशिक नकली है (ऑब्जेक्ट का हिस्सा मजाक किया जाएगा और भाग वास्तविक विधि आमंत्रण का उपयोग करेगा)।

+1

तो दूसरे पर एक का उपयोग कब करें? –

+0

@ इगोरगानापोलस्की: यह आपके उपयोग के मामले पर निर्भर करता है। :-) – Sipty

8

मैं एक ruanble उदाहरण यहाँ https://www.surasint.com/mockito-with-spy/

मैं यहाँ इसके बारे में कुछ नकल बनाया है।

आप इस कोड की तरह कुछ है, तो:

public void transfer( DepositMoneyService depositMoneyService, WithdrawMoneyService withdrawMoneyService, 
      double amount, String fromAccount, String toAccount){ 
    withdrawMoneyService.withdraw(fromAccount,amount); 
    depositMoneyService.deposit(toAccount,amount); 
} 

आप जासूस की जरूरत नहीं है सकते हैं क्योंकि आप सिर्फ नकली DepositMoneyService और WithdrawMoneyService कर सकते हैं।

लेकिन कुछ विरासत कोड के साथ, निर्भरता इस तरह कोड में है:

public void transfer(String fromAccount, String toAccount, double amount){ 

     this.depositeMoneyService = new DepositMoneyService(); 
     this.withdrawMoneyService = new WithdrawMoneyService(); 

     withdrawMoneyService.withdraw(fromAccount,amount); 
     depositeMoneyService.deposit(toAccount,amount); 
    } 

हाँ, आप पहली बार कोड को बदल सकते हैं, लेकिन फिर एपीआई बदल जाता है। यदि इस विधि का उपयोग कई स्थानों द्वारा किया जा रहा है, तो आपको उन सभी को बदलना होगा।

वैकल्पिक है कि आप निर्भरता इस तरह बाहर निकाल सकते हैं: लिंक में ऊपर

DepositMoneyService mockDepositMoneyService = mock(DepositMoneyService.class); 
     WithdrawMoneyService mockWithdrawMoneyService = mock(WithdrawMoneyService.class); 

    TransferMoneyService target = spy(new TransferMoneyService()); 

    doReturn(mockDepositMoneyService) 
      .when(target).proxyDepositMoneyServiceCreator(); 

    doReturn(mockWithdrawMoneyService) 
      .when(target).proxyWithdrawMoneyServiceCreator(); 

अधिक विस्तार:

public void transfer(String fromAccount, String toAccount, double amount){ 
     this.depositeMoneyService = proxyDepositMoneyServiceCreator(); 
     this.withdrawMoneyService = proxyWithdrawMoneyServiceCreator(); 

     withdrawMoneyService.withdraw(fromAccount,amount); 
     depositeMoneyService.deposit(toAccount,amount); 
    } 
    DepositMoneyService proxyDepositMoneyServiceCreator() { 
     return new DepositMoneyService(); 
    } 

    WithdrawMoneyService proxyWithdrawMoneyServiceCreator() { 
     return new WithdrawMoneyService(); 
    } 

तो फिर तुम जासूस इंजेक्षन इस तरह निर्भरता का उपयोग कर सकते हैं।

2

टी एल; डॉ संस्करण,

नकली साथ

, यह आप के लिए एक नंगे हड्डी खोल उदाहरण पैदा करता है।

List<String> mockList = Mockito.mock(ArrayList.class); 
जासूस के साथ

आप कर सकते हैं एक मौजूदा उदाहरण

List<String> spyList = Mockito.spy(new ArrayList<String>()); 

जासूस के लिए विशिष्ट उपयोग के मामले पर आंशिक रूप से नकली: कक्षा एक पैरामिट्रीकृत निर्माता है, तो आपको पहले वस्तु बनाना चाहते हैं।

0

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

जासूसी वस्तुओं में, निश्चित रूप से, क्योंकि यह एक असली विधि है, जब आप विधि को दबा नहीं रहे हैं, तो यह वास्तविक विधि व्यवहार को कॉल करेगा। यदि आप विधि को बदलना और नकल करना चाहते हैं, तो आपको इसे रोकना होगा।

तुलना के रूप में नीचे दिए गए उदाहरण पर विचार करें।

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.mockito.Spy; 
import org.mockito.runners.MockitoJUnitRunner; 
  
import java.util.ArrayList; 
import java.util.List; 
  
import static org.junit.Assert.assertEquals; 
import static org.junit.Assert.assertNull; 
import static org.mockito.Mockito.doReturn; 
import static org.mockito.Mockito.when; 
  
@RunWith(MockitoJUnitRunner.class) 
public class MockSpy { 
  
    @Mock 
    private List<String> mockList; 
  
    @Spy 
    private List<String> spyList = new ArrayList(); 
  
    @Test 
    public void testMockList() { 
        //by default, calling the methods of mock object will do nothing 
        mockList.add("test"); 

     Mockito.verify(mockList).add("test"); 
     assertEquals(0, mockList.size()); 
        assertNull(mockList.get(0)); 
    } 
  
    @Test 
    public void testSpyList() { 
        //spy object will call the real method when not stub 
        spyList.add("test"); 

     Mockito.verify(spyList).add("test"); 
     assertEquals(1, spyList.size()); 
        assertEquals("test", spyList.get(0)); 
    } 
  
    @Test 
    public void testMockWithStub() { 
        //try stubbing a method 
        String expected = "Mock 100"; 
        when(mockList.get(100)).thenReturn(expected); 
  
        assertEquals(expected, mockList.get(100)); 
    } 
  
    @Test 
    public void testSpyWithStub() { 
        //stubbing a spy method will result the same as the mock object 
        String expected = "Spy 100"; 
        //take note of using doReturn instead of when 
        doReturn(expected).when(spyList).get(100); 
  
        assertEquals(expected, spyList.get(100)); 
    } 
} 

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

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