खोज…


सिंपल मॉक

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

Dependency mock = Mockito.mock(Dependency.class);

यह Dependency का एक नकली उदाहरण बनाता है चाहे Dependency एक इंटरफ़ेस या वर्ग हो।

Mockito.when (x) .thenReturn (y) संकेतन का उपयोग करके उस मॉक को कॉल करने की विधि को स्टब करना संभव है।

Mockito.when(mock.possiblyBuggyMethod()).thenReturn("someString");

इसलिए कि Dependency.possiblyBuggyMethod() लिए कॉल करें। "someString" Dependency.possiblyBuggyMethod() बस "someString" लौटें।

एक और संकेतन है जो अधिकांश उपयोग के मामलों में हतोत्साहित किया जाता है क्योंकि यह टाइपसेफ़ नहीं है।

Mockito.doReturn("someString").when(mock).possiblyBuggyMethod()

चूक के साथ मजाक

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

Dependency mock = Mockito.mock(Dependency.class, new Answer() {

        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            return "someString";
        }
    });

या मेमने का उपयोग कर:

Dependency mock = Mockito.mock(Dependency.class, (Answer) invocationOnMock -> "someString");

यह उदाहरण हर आह्वान पर "someString" लौटाता है लेकिन उत्तर-विधि में किसी भी तर्क को परिभाषित करना संभव है।

एनोटेशन का उपयोग करके एक वर्ग का मजाक उड़ाना

परीक्षण के तहत कक्षा:

public class GreetingsService { // class to be tested in isolation
    private UserService userService;

    public GreetingsService(UserService userService) {
        this.userService = userService;
    }

    public String getGreetings(int userId, LocalTime time) { // the method under test
        StringBuilder greetings = new StringBuilder();
        String timeOfDay = getTimeOfDay(time.getHour());
        greetings.append("Good ").append(timeOfDay).append(", ");
        greetings.append(userService.getFirstName(userId)) // this call will be mocked
                .append(" ")
                .append(userService.getLastName(userId)) // this call will be mocked
                .append("!");
        return greetings.toString();
    }

    private String getTimeOfDay(int hour) { // private method doesn't need to be unit tested
        if (hour >= 0 && hour < 12)
            return "Morning";
        else if (hour >= 12 && hour < 16)
            return "Afternoon";
        else if (hour >= 16 && hour < 21)
            return "Evening";
        else if (hour >= 21 && hour < 24)
            return "Night";
        else
            return null;
    }
}

इस इंटरफ़ेस का व्यवहार मज़ाक उड़ाया जाएगा:

public interface UserService {
    String getFirstName(int userId);

    String getLastName(int userId);
}

मान लें की वास्तविक क्रियान्वयन UserService :

public class UserServiceImpl implements UserService {
    @Override
    public String getFirstName(int userId) {
        String firstName = "";
        // some logic to get user's first name goes here
        // this could be anything like a call to another service,
        // a database query, or a web service call
        return firstName;
    }

    @Override
    public String getLastName(int userId) {
        String lastName = "";
        // some logic to get user's last name goes here
        // this could be anything like a call to another service,
        // a database query, or a web service call
        return lastName;
    }
}

मॉकिटो के साथ जूनिट टेस्ट:

public class GreetingsServiceTest {
    @Mock
    private UserServiceImpl userService; // this class will be mocked
    @InjectMocks
    private GreetingsService greetingsService = new GreetingsService(userService);

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

    @Test
    public void testGetGreetings_morning() throws Exception {
        // specify mocked behavior
        when(userService.getFirstName(99)).thenReturn("John");
        when(userService.getLastName(99)).thenReturn("Doe");
        // invoke method under test
        String greetings = greetingsService.getGreetings(99, LocalTime.of(0, 45));
        Assert.assertEquals("Failed to get greetings!", "Good Morning, John Doe!", greetings);
    }

    @Test
    public void testGetGreetings_afternoon() throws Exception {
        // specify mocked behavior
        when(userService.getFirstName(11)).thenReturn("Jane");
        when(userService.getLastName(11)).thenReturn("Doe");
        // invoke method under test
        String greetings = greetingsService.getGreetings(11, LocalTime.of(13, 15));
        Assert.assertEquals("Failed to get greetings!", "Good Afternoon, Jane Doe!", greetings);
    }
}

आंशिक मजाक के लिए "जासूस"

@Spy एनोटेशन (या विधि ) का उपयोग किसी वस्तु को आंशिक रूप से नकली करने के लिए किया जा सकता है। यह तब उपयोगी होता है जब आप किसी वर्ग के व्यवहार का आंशिक रूप से मजाक करना चाहते हैं। उदाहरण के लिए मान लें कि आपके पास एक वर्ग है जो दो अलग-अलग सेवाओं का उपयोग करता है और आप उनमें से केवल एक का मजाक उड़ाते हैं और दूसरी सेवा के वास्तविक कार्यान्वयन का उपयोग करते हैं।

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

Class under test:
public class GreetingsService { // class to be tested in isolation
    private UserService userService;
    private AppService appService;

    public GreetingsService(UserService userService, AppService appService) {
        this.userService = userService;
        this.appService = appService;
    }

    public String getGreetings(int userId, LocalTime time) { // the method under test
        StringBuilder greetings = new StringBuilder();
        String timeOfDay = getTimeOfDay(time.getHour());
        greetings.append("Good ").append(timeOfDay).append(", ");
        greetings.append(userService.getFirstName(userId)) // this call will be mocked
                .append(" ")
                .append(userService.getLastName(userId)) // this call will be mocked
                .append("!");
        greetings.append(" Welcome to ")
                .append(appService.getAppName()) // actual method call will be made
                .append(".");
        return greetings.toString();
    }

    private String getTimeOfDay(int hour) { // private method doesn't need to be unit tested
        if (hour >= 0 && hour < 12)
            return "Morning";
        else if (hour >= 12 && hour < 16)
            return "Afternoon";
        else if (hour >= 16 && hour < 21)
            return "Evening";
        else if (hour >= 21 && hour < 24)
            return "Night";
        else
            return null;
    }
}

इस इंटरफ़ेस का व्यवहार मज़ाक उड़ाया जाएगा:

public interface UserService {
    String getFirstName(int userId);

    String getLastName(int userId);
}

मान लें की वास्तविक क्रियान्वयन UserService :

public class UserServiceImpl implements UserService {
    @Override
    public String getFirstName(int userId) {
        String firstName = "";
        // some logic to get user's first name
        // this could be anything like a call to another service,
        // a database query, or a web service call
        return firstName;
    }

    @Override
    public String getLastName(int userId) {
        String lastName = "";
        // some logic to get user's last name
        // this could be anything like a call to another service,
        // a database query, or a web service call
        return lastName;
    }
}

इस इंटरफ़ेस के व्यवहार का मज़ाक नहीं उड़ाया जाएगा:

public interface AppService {
    String getAppName();
}

मान लें कि AppService का वास्तविक कार्यान्वयन:

public class AppServiceImpl implements AppService {
    @Override
    public String getAppName() {
        // assume you are reading this from properties file
        String appName = "The Amazing Application";
        return appName;
    }
}

मॉकिटो के साथ जूनिट टेस्ट:

public class GreetingsServiceTest {
    @Mock
    private UserServiceImpl userService; // this class will be mocked
    @Spy
    private AppServiceImpl appService; // this class WON'T be mocked
    @InjectMocks
    private GreetingsService greetingsService = new GreetingsService(userService, appService);

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

    @Test
    public void testGetGreetings_morning() throws Exception {
        // specify mocked behavior
        when(userService.getFirstName(99)).thenReturn("John");
        when(userService.getLastName(99)).thenReturn("Doe");
        // invoke method under test
        String greetings = greetingsService.getGreetings(99, LocalTime.of(0, 45));
        Assert.assertEquals("Failed to get greetings!", "Good Morning, John Doe! Welcome to The Amazing Application.", greetings);
    }

    @Test
    public void testGetGreetings_afternoon() throws Exception {
        // specify mocked behavior
        when(userService.getFirstName(11)).thenReturn("Jane");
        when(userService.getLastName(11)).thenReturn("Doe");
        // invoke method under test
        String greetings = greetingsService.getGreetings(11, LocalTime.of(13, 15));
        Assert.assertEquals("Failed to get greetings!", "Good Afternoon, Jane Doe! Welcome to The Amazing Application.", greetings);
    }
}

नकली वस्तुओं में निजी क्षेत्र निर्धारित करें

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

@InjectMocks
private GreetingsService greetingsService = new GreetingsService(); // mocking this class

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    String someName = "Some Name";
    ReflectionTestUtils.setField(greetingsService, // inject into this object
        "name", // assign to this field
        someName); // object to be injected
}

मैं यहाँ सरल बनाने के लिए Sptring's ReflectionTestUtils.setField(Object targetObject, String name, Object value) विधि का उपयोग कर रहा हूँ, लेकिन आप इसे करने के लिए सादे पुराने Java Reflection का उपयोग कर सकते हैं।



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