खोज…


टिप्पणियों

मॉकिटो एक जावा मॉकिंग फ्रेमवर्क है जिसका उद्देश्य सरल एपीआई का उपयोग करके एक पठनीय इकाई परीक्षणों को साफ करने की क्षमता प्रदान करना है। यह अन्य मॉकिंग फ्रेमवर्क से भिन्न है जो कि अपेक्षित रन-वेरी पैटर्न को छोड़ कर उपयोग करता है जो कि अधिकांश अन्य फ्रेमवर्क उपयोग करते हैं।

इसके बजाय यह केवल (गैर-अंतिम) कक्षाओं और इंटरफेस को मॉक करने का एक तरीका जानता है और लचीले तर्क मिलानकर्ताओं के आधार पर सत्यापित और स्टब करने की अनुमति देता है।

वर्तमान संस्करण 1.10.19 को मावेन का उपयोग करके सबसे अच्छा प्राप्त किया गया है

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.10.19</version>
</dependency>

या ढाल

repositories { jcenter() }
dependencies { testCompile "org.mockito:mockito-core:1.+" }

संस्करण 2 अभी भी बीटा में है।

संस्करण

संस्करण मावेन सेंट्रल रिलीज नोट्स रिलीज़ की तारीख
2.1.0 mockito कोर परिवर्तन 2016/10/04
1.10.19 mockito कोर परिवर्तन 2014-12-31

मॉकिटो का उपयोग करके सरल इकाई परीक्षण

हम जिस वर्ग का परीक्षण करने जा रहे हैं वह है:

public class Service {

    private Collaborator collaborator;

    public Service(Collaborator collaborator) {
        this.collaborator = collaborator;
    }
    
    public String performService(String input) {
        return collaborator.transformString(input);
    }
}

इसके सहयोगी हैं:

public class Collaborator {

    public String transformString(String input) {
        return doStuff();
    }

    private String doStuff() {
        // This method may be full of bugs
        . . .
        return someString;
    }

}

हमारे परीक्षण में, हम Collaborator और उसके बगों से निर्भरता को तोड़ना चाहते हैं, इसलिए हम Collaborator का मजाक उड़ाने जा रहे हैं:

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.junit.Test;

public class ServiceTest {
    @Test
    public void testPerformService() throws Exception {
        // Configure mock
        Collaborator collaboratorMock = mock(Collaborator.class);
        doReturn("output").when(collaboratorMock).transformString("input");

        // Perform the test
        Service service = new Service(collaboratorMock);
        String actual = service.performService("input");
        
        // Junit asserts
        String expected = "output";
        assertEquals(expected, actual);
    }  
}

मॉकिटो एनोटेशन का उपयोग करना

हम जिस वर्ग का परीक्षण करने जा रहे हैं वह है:

public class Service{

    private Collaborator collaborator;

    public Service(Collaborator collaborator){
        this.collaborator = collaborator;
    }
    
    
    public String performService(String input){
        return collaborator.transformString(input);
    }
}

इसके सहयोगी हैं:

public class Collaborator {

    public String transformString(String input){
        return doStuff();
    }

    private String doStuff()
    {
        // This method may be full of bugs
        . . .
        return someString;
    }

}

हमारे परीक्षण में, हम Collaborator और इसकी बग्स से निर्भरता को तोड़ना चाहते हैं, इसलिए हम Collaborator का मजाक बनाने जा रहे हैं। @Mock एनोटेशन का उपयोग करना प्रत्येक परीक्षण के लिए विभिन्न उदाहरणों को बनाने के लिए एक सुविधाजनक तरीका है:

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

    @Mock
    private Collaborator collaboratorMock;

    @InjectMocks
    private Service service;
    
    @Test
    public void testPerformService() throws Exception {
        // Configure mock
        doReturn("output").when(collaboratorMock).transformString("input");            

        // Perform the test
        String actual = service.performService("input");
        
        // Junit asserts
        String expected = "output";
        assertEquals(expected, actual);
    }
    
    
    @Test(expected=Exception.class)
    public void testPerformServiceShouldFail() throws Exception {
        // Configure mock
        doThrow(new Exception()).when(collaboratorMock).transformString("input");

        // Perform the test
        service.performService("input");
    }
}

मॉकिटो निम्नलिखित क्रम में निर्भरता इंजेक्शन को हल करने की कोशिश करेगा:

  1. कंस्ट्रक्टर-आधारित इंजेक्शन - मोक्स को कंस्ट्रक्टर में अधिकांश तर्कों के साथ इंजेक्ट किया जाता है (यदि कुछ तर्क नहीं मिल सकते हैं, तो नल पास हो जाते हैं)। यदि किसी ऑब्जेक्ट को कंस्ट्रक्टर के माध्यम से सफलतापूर्वक बनाया गया था, तो कोई अन्य रणनीति लागू नहीं की जाएगी।
  2. सेटर-आधारित इंजेक्शन - मोक्स को प्रकार द्वारा इंजेक्ट किया जाता है। यदि एक ही प्रकार के कई गुण हैं, तो संपत्ति के नाम और नकली नामों का मिलान किया जाएगा।
  3. प्रत्यक्ष क्षेत्र इंजेक्शन - सेटर-आधारित इंजेक्शन के लिए समान।

ध्यान दें कि यदि कोई पूर्वोक्त रणनीति विफल रही तो किसी भी विफलता की सूचना नहीं है।

Mockito के नवीनतम संस्करण में इस तंत्र पर अधिक विस्तृत जानकारी के लिए नवीनतम @InjectMocks से परामर्श करें।

स्थापना और सेटअप

स्थापना

mockito-core को स्थापित करने का पसंदीदा तरीका mockito-core पर निर्भरता को पसंद की निर्माण प्रणाली के साथ घोषित करना है। 22 जुलाई, 2016 तक, नवीनतम गैर-बीटा संस्करण 1.10.19 है, लेकिन 2.x को पहले से ही माइग्रेट करने के लिए प्रोत्साहित किया जाता है

Maven

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
</dependency>

Gradle

repositories { jcenter() }
dependencies { testCompile "org.mockito:mockito-core:1.+" }

इसमें mockito-all भी है जिसमें मॉकिटो के अलावा हैमरेस्ट और ओबजेनेसिस भी हैं। यह मुख्य रूप से चींटी उपयोगकर्ताओं के लिए मावेन के माध्यम से दिया जाता है, लेकिन मॉकिटो 2.x में वितरण बंद कर दिया गया है।


आयात

org.mockito.Mockito सुविधाओं के अधिकांश org.mockito.Mockito स्थिर तरीके हैं। इस प्रकार, मॉकिटो को इस तरह से एक वर्ग में सांख्यिकीय रूप से आयात किया जा सकता है:

import static org.mockito.Mockito.*;

प्रलेखन प्रविष्टि बिंदु इस वर्ग के javadoc में स्थित है।

किसी वस्तु पर कुछ विधियों का मजाक उड़ाना

किसी वस्तु के बस कुछ तरीकों का मॉकिटो के स्पाई spy() का उपयोग करके मजाक किया जा सकता है।

उदाहरण के लिए, कल्पना करें कि विधि वर्ग को काम करने के लिए कुछ वेब सेवा की आवश्यकता होती है।

public class UserManager {

    List<User> users;        

    public UserManager() {
        user = new LinkedLisk<User>();
    }
    
    public void addUser(User user) {
        if (isValid(user)) {
            user.add(user);
        } else {
            throw new NotValidUserException();
        }
    }
    
    protected boolean isValid(User user) {
        //some online web service to check if user is valid
    }
    
    public int numberOfUsers() {
        return users.size();
    }
}

addUser लिए एक उपयोगी परीक्षण करने के लिए UserManager विधि का परीक्षण किया जाना चाहिए। हालांकि, एक निर्भरता यहां पाई जाती है, isValid को एक बाहरी वेब सेवा की आवश्यकता होती है जो हमारे कोड में निहित नहीं है। फिर, इस बाहरी निर्भरता को निष्प्रभावी किया जाना चाहिए।

इस मामले में, अगर आप केवल नकली isValid आप के बाकी का परीक्षण करने में सक्षम हो जाएगा UserManager तरीकों।

@Test
public void testAddUser() {
    User user = mock(User.class);
    UserManager  manager = spy(new UserManager());
    
    //it forces to manager.isValid to return true
    doReturn(true).when(manager).isValid(anyObject());
    
    manager.addUser(user);
    assertTrue(manager.numberOfUsers(), 1);
} 

आप आसानी से उस परिदृश्य की जाँच कर सकते हैं जहाँ user मान्य नहीं है।

@Test(expectedExceptions = NotValidUserException.class)
public void testNotValidAddUser() {
    User user = mock(User.class);
    UserManager  manager = spy(new UserManager());
    
    //it forces to manager.isValid to return false
    doReturn(false).when(manager).isValid(anyObject());
    
    manager.addUser(user);
} 

सरल न्यूनतम मॉकिटो टेस्ट

यह उदाहरण एक नकली ArrayList का उपयोग करके न्यूनतम मॉकिटो परीक्षण दिखाता है:

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest
{
    @Mock
    ArrayList<String> listMock;

    @Test
    public void testAppend() {
        // configure the mock to return "foobar" whenever "get()" 
        // is called on "listMock" with an int value as parameter
        doReturn("foobar").when(listMock).get(anyInt());            
        String result = listMock.get(0);
        
        assertEquals("foobar", result);
    }
}

ArgumentCaptor के साथ तर्कों का सत्यापन करना

एक मॉक पर बताए गए तरीकों के लिए तर्कों को मान्य करने के लिए, ArgumentCaptor वर्ग का उपयोग करें। यह आपको अपने परीक्षण पद्धति में तर्कों को निकालने और उन पर दावे करने की अनुमति देगा।

यह उदाहरण एक विधि का परीक्षण करता है जो किसी दिए गए आईडी के साथ उपयोगकर्ता के नाम को अपडेट करता है। विधि उपयोगकर्ता को लोड करती है, दिए गए मान के साथ name विशेषता को अपडेट करती है और बाद में इसे सहेजती है। परीक्षण यह सत्यापित करना चाहता है कि save विधि में दिया गया तर्क सही आईडी और नाम के साथ एक User ऑब्जेक्ट है।

// This is mocked in the test
interface UserDao {
    void save(User user);
}

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
    @Mock
    UserDao userDao;

    @Test
    public void testSetNameForUser() {
        UserService serviceUnderTest = new UserService(userDao);
        
        serviceUnderTest.setNameForUser(1L, "John");

        ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class);
        
        verify(userDao).save(userArgumentCaptor.capture());
        User savedUser = userArgumentCaptor.getValue();
        assertTrue(savedUser.getId() == 1);
        assertTrue(savedUser.getName().equals("John"));
    }
}

ArgumentMatcher के साथ तर्क का सत्यापन

Mockito तर्कों को सत्यापित करने के लिए एक सार ArgumentMatcher<T> वर्ग के साथ एक Matcher<T> इंटरफ़ेस प्रदान करता है। यह ArgumentCaptor तुलना में समान उपयोग-केस के लिए एक अलग दृष्टिकोण का उपयोग करता है। इसके अतिरिक्त ArgumentMatcher का उपयोग मॉकिंग में भी किया जा सकता है। दोनों उपयोग-मामले Mockito.argThat() विधि का उपयोग करते हैं जो एक उचित पठनीय परीक्षण कोड प्रदान करता है।

verify(someMock).someMethod(Mockito.argThat(new ArgumentMatcher<String>() {
       
    @Override
    public boolean matches(Object o) {
        return o instanceof String && !((String)o).isEmpty();
    }

});        

ArgumentMatcher के JavaDocs से:

चेतावनी: जटिल तर्क मिलान, विशेष रूप से कस्टम तर्क मिलानकर्ताओं का उपयोग करने के साथ उचित रहें, क्योंकि यह परीक्षण को कम पठनीय बना सकता है। कभी-कभी मॉक करने के लिए पारित होने वाले तर्कों के लिए समान () को लागू करना बेहतर होता है (मॉकिटो स्वाभाविक रूप से तर्क के लिए बराबरी का उपयोग करता है (तर्क मिलान के लिए)। इससे टेस्ट क्लीनर बन सकता है।

मॉकिटो द्वारा नकली वस्तुओं का निर्माण करें

मॉकिटो द्वारा नकली वस्तु बनाने के दो तरीके हैं:

  • एनोटेशन के जरिए
  • मॉक फंक्शन के जरिए

एनोटेशन:

JUnit टेस्ट रनर के साथ:

@RunWith(MockitoJUnitRunner.class)
public class FooTest {
    @Mock
    private Bar barMock;

    // ...
}

तुम भी Mockito के JUnit उपयोग कर सकते हैं @Rule है, जो के रूप में ही सुविधा प्रदान करता है MockitoJUnitRunner , लेकिन एक की जरूरत नहीं है @RunWith परीक्षण धावक:

public class FooTest {
    @Rule
    public MockitoRule mockito = MockitoJUnit.rule();        

    @Mock
    private Bar barMock;

    // ...
}

यदि आप @RunWith या @Rule एनोटेशन का उपयोग नहीं कर सकते हैं, तो आप "प्रति हाथ" @Rule को भी @Rule सकते हैं:

public class FooTest {
    @Mock
    private Bar barMock;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    // ...
}

नकली समारोह:

public class FooTest {
    private Bar barMock = Mockito.mock(Bar.class);

    // ...
}

प्रकार के क्षरण के कारण, आप ऊपर के रूप में एक सामान्य वर्ग का मजाक नहीं उड़ा सकते। आपको बेस क्लास का मज़ाक उड़ाना चाहिए और स्पष्ट रूप से सही जेनेरिक प्रकार कास्ट करना होगा:

public class FooTest {
    private Bar<String> genericBarMock = (Bar<String>) Mockito.mock(Bar.class);

    // ...
}

नकली वस्तु में व्यवहार जोड़ें

Mockito.when(mock.returnSomething()).thenReturn("my val");

mock.returnSomething(); // returns "my val"
mock.returnSomething(); // returns "my val" again
mock.returnSomething(); // returns "my val" again and again and again...

यदि आप दूसरी कॉल पर अलग मूल्य चाहते हैं तो आप तत्कालीन रिटर्न विधि में वांछित रिटर्न तर्क जोड़ सकते हैं:

Mockito.when(mock.returnSomething()).thenReturn("my val", "other val");

mock.returnSomething(); // returns "my val"
mock.returnSomething(); // returns "other val"
mock.returnSomething(); // returns "other val" again

यदि आप पद्धति को बिना व्यवहार के जोड़ देंगे तो यह शून्य हो जाएगी।

barMock.mock.returnSomethingElse(); // returns null

इस मामले में कि नकली विधि में पैरामीटर हैं, आपको मान भी घोषित करना चाहिए:

Mockito.when(mock.returnSomething("param 1")).thenReturn("my val 1");
Mockito.when(mock.returnSomething("param 2")).thenReturn("my val 2");

mock.returnSomething("param 1"); // returns "my val 1"
mock.returnSomething("param 2"); // returns "my val 2"
mock.returnSomething("param 3"); // returns null

यदि आप परम मूल्य के बारे में परवाह नहीं करते हैं तो आप Matchers.any () का उपयोग कर सकते हैं:

Mockito.when(mock.returnSomething(Matchers.any())).thenReturn("p1");

mock.returnSomething("param 1"); // returns "p1"
mock.returnSomething("param other"); // returns "p1"

अपवाद का उपयोग करने के लिए तब फेंक विधि:

Mockito.when(mock.returnSomething()).thenThrow(new Exception());

mock.returnSomething(); // throws Exception

मॉक पास करने के लिए तर्कों की जाँच करें

मान लें कि हमारे पास यह वर्ग है और हम doSmth विधि का परीक्षण करना चाहते हैं। इस मामले में हम यह देखना चाहते हैं कि क्या पैरामीटर "वैल" foo लिए पारित किया गया है। ऑब्जेक्ट foo का मजाक उड़ाया जाता है।

public class Bar {

    private final Foo foo;

    public Bar(final Foo foo) {
        this.foo = foo;
    }

    public void doSmth() {
        foo.bla("val");
    }
}

हम इसे ArgumentCaptor साथ प्राप्त कर सकते हैं:

@Mock
private Foo fooMock;

@InjectMocks
private Bar underTest;

@Captor
private ArgumentCaptor<String> stringCaptor;

@Test
public void should_test_smth() {
    underTest.doSmth();

    Mockito.verify(fooMock).bla(stringCaptor.capture());

    assertThat(stringCaptor.getValue(), is("val"));
}

नकली वस्तु पर विधि कॉल सत्यापित करें

यह जांचने के लिए कि क्या विधि को किसी Mockito.verify वस्तु पर बुलाया गया है, आप Mockito.verify उपयोग कर सकते हैं। विधि का उपयोग करें:

Mockito.verify(someMock).bla();

इस उदाहरण में, हम दावा करते हैं कि विधि bla को someMock मॉक ऑब्जेक्ट पर बुलाया गया था।

आप यह भी देख सकते हैं कि क्या कोई विधि कुछ मापदंडों के साथ बुलाई गई थी:

Mockito.verify(someMock).bla("param 1");

यदि आप जांचना चाहते हैं कि कोई विधि नहीं बुलाई गई थी, तो आप verify करने के verify एक अतिरिक्त VerificationMode पारित कर सकते हैं:

Mockito.verify(someMock, Mockito.times(0)).bla();

यह भी काम करता है यदि आप यह जांचना चाहते हैं कि इस विधि को एक से अधिक बार कहा गया था (इस मामले में हम जाँचते हैं कि विधि bla 23% कहलाती है):

Mockito.verify(someMock, Mockito.times(23)).bla();

VerificationMode विधि के लिए ये अधिक उदाहरण हैं, विधि को बुलाए जाने की संख्या पर अधिक नियंत्रण प्रदान करना चाहिए:

Mockito.verify(someMock, Mockito.never()).bla(); // same as Mockito.times(0)

Mockito.verify(someMock, Mockito.atLeast(3)).bla(); // min 3 calls

Mockito.verify(someMock, Mockito.atLeastOnce()).bla(); // same as Mockito.atLeast(1)

Mockito.verify(someMock, Mockito.atMost(3)).bla(); // max 3 calls

शून्य तरीकों को ठोकर मारना

void तरीकों को doThrow () , doAnswer () , doNothing () , doCallRealMethod () तरीकों के परिवार का उपयोग करके स्टब किया जा सकता है।

Runnable mock = mock(Runnable.class);

doThrow(new UnsupportedOperationException()).when(mock).run();

mock.run(); // throws the UnsupportedOperationException

ध्यान दें कि void तरीकों का उपयोग कर टोंटदार नहीं किया जा सकता when(..) संकलक कारण पसंद नहीं void तर्क के रूप में तरीकों।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow