@Mock, @ MockBean और Mockito.mock () के बीच अंतर


147

परीक्षण बनाते समय और निर्भरता का मज़ाक उड़ाते हुए, इन तीन दृष्टिकोणों में क्या अंतर है?

  1. @MockBean:

    @MockBean
    MyService myservice;
    
  2. @Mock:

    @Mock
    MyService myservice;
    
  3. Mockito.mock ()

    MyService myservice = Mockito.mock(MyService.class);

जवाबों:


198

सादा मॉकिटो लाइब्रेरी

import org.mockito.Mock;
...
@Mock
MyService myservice;

तथा

import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);

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

एनोटेशन का उपयोग करने का तरीका छोटा है, इसलिए बेहतर और अक्सर पसंद किया जाता है।


ध्यान दें कि परीक्षण निष्पादन के दौरान मॉकिटो एनोटेशन को सक्षम करने के लिए, MockitoAnnotations.initMocks(this)स्थिर विधि को कॉल करना होगा।
परीक्षणों के बीच साइड इफेक्ट से बचने के लिए, प्रत्येक परीक्षण के निष्पादन से पहले इसे करने की सलाह दी जाती है:

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

मॉकिटो एनोटेशन को सक्षम करने का एक और तरीका @RunWithयह है MockitoJUnitRunnerकि यह काम करता है और अन्य उपयोगी जानकारी निर्दिष्ट करके परीक्षण वर्ग की व्याख्या कर रहा है :

@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}

मॉकिटो लाइब्रेरी को लपेटने वाली स्प्रिंग बूट लाइब्रेरी

यह वास्तव में एक स्प्रिंग बूट क्लास है :

import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;

spring-boot-testलाइब्रेरी में क्लास शामिल है ।

यह एक स्प्रिंग में मॉकिटो मोक्स को जोड़ने की अनुमति देता है ApplicationContext
यदि एक बीन, घोषित वर्ग के साथ संगत संदर्भ में मौजूद है, तो यह मॉक द्वारा प्रतिस्थापित करता है।
यदि यह मामला नहीं है, तो यह संदर्भ में मॉक को सेम के रूप में जोड़ता है।

जावदोक संदर्भ:

एक स्प्रिंग ApplicationContext में मोक्स को जोड़ने के लिए इस्तेमाल किया जाने वाला एनोटेशन।

...

यदि संदर्भ में परिभाषित उसी प्रकार के किसी भी मौजूदा एकल बीन को मॉक द्वारा प्रतिस्थापित किया जाएगा, यदि कोई मौजूदा बीन परिभाषित नहीं किया गया है तो एक नया जोड़ा जाएगा।


क्लासिक / सादे मॉकिटो का उपयोग कब करें @MockBeanऔर स्प्रिंग बूट से कब उपयोग करें ?

यूनिट परीक्षणों को अन्य घटकों से अलगाव में एक घटक का परीक्षण करने के लिए डिज़ाइन किया गया है और इकाई परीक्षणों की भी आवश्यकता है: निष्पादन समय के मामले में जितना संभव हो उतना तेज़ हो सकता है क्योंकि इन परीक्षणों को डेवलपर मशीनों पर प्रत्येक दिन दर्जनों बार निष्पादित किया जा सकता है।

नतीजतन, यहाँ एक सरल दिशानिर्देश है:

जैसा कि आप एक परीक्षण लिखते हैं जिसे स्प्रिंग बूट कंटेनर से किसी भी निर्भरता की आवश्यकता नहीं होती है, क्लासिक / सादा मॉकिटो इसका अनुसरण करने का तरीका है: यह तेज़ है और परीक्षण किए गए घटक के अलगाव का पक्षधर है।
यदि आपके परीक्षण को स्प्रिंग बूट कंटेनर पर भरोसा करने की आवश्यकता है और आप कंटेनर बीन्स में @MockBeanसे एक को जोड़ना या नकली करना भी चाहते हैं: स्प्रिंग बूट का तरीका है।


स्प्रिंग बूट का विशिष्ट उपयोग @MockBean

जैसा कि हम लिखते हैं कि एक टेस्ट क्लास एनोटेट @WebMvcTest(वेब टेस्ट स्लाइस) है।

स्प्रिंग बूट प्रलेखन बहुत अच्छी तरह से सारांशित करता है:

अक्सर @WebMvcTestएक ही नियंत्रक तक सीमित होगा और @MockBeanआवश्यक सहयोगियों के लिए नकली कार्यान्वयन प्रदान करने के लिए संयोजन में उपयोग किया जाएगा ।

यहाँ एक उदाहरण है :

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(FooController.class)
public class FooControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private FooService fooServiceMock;

    @Test
    public void testExample() throws Exception {
         Foo mockedFoo = new Foo("one", "two");

         Mockito.when(fooServiceMock.get(1))
                .thenReturn(mockedFoo);

         mvc.perform(get("foos/1")
            .accept(MediaType.TEXT_PLAIN))
            .andExpect(status().isOk())
            .andExpect(content().string("one two"));
    }

}

4
@MockBean का उपयोग करने से बीन की एक प्रति बन जाएगी और इसे ApplicationContext पर इंजेक्ट कर देगा? या नकली बीन के सभी तरीके अशक्त होंगे? यदि सभी विधियाँ शून्य हैं तो क्या मैं उन्हें रोक सकता हूं जैसे कि मैं @Mock का उपयोग कर सकता हूं?
डग

6
जैसा कि समझाया गया है, का उपयोग करके @MockBeanबीन को एप्लिकेशन संदर्भ में बदल दिया जाएगा यदि उसी प्रकार की घोषणा करने वाला बीन आपके स्प्रिंग कॉन्फ़िगरेशन में पहले से ही परिभाषित है। और इंजेक्शन उस कक्षा में किया जाता है जहां आप घोषणा करते हैं @MockBean.कि डीआई तंत्र इस तरह से काम करता है: आप डीआई संदर्भ में एक ऑब्जेक्ट रजिस्टर करते हैं और फिर आप किसी विशिष्ट वर्ग में स्प्रिंग संदर्भ में संदर्भित ऑब्जेक्ट को इंजेक्ट कर सकते हैं। आप किसी ऑब्जेक्ट को DI संदर्भ में इंजेक्ट नहीं करते हैं।
davidxxx

13

अंत में इसकी व्याख्या आसान है। यदि आप केवल एनोटेशन के javadocs में देखते हैं तो आपको विभिन्नताएँ दिखाई देंगी:

@ मॉक: ( org.mockito.Mock)

एक क्षेत्र को मॉक के रूप में चिह्नित करें।

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

@MockBean: ( org.springframework.boot.test.mock.mockito.MockBean)

एनोटेशन जिसका उपयोग स्प्रिंग एप्लीकेशन कॉन्टेक्स्ट में मोक्स को जोड़ने के लिए किया जा सकता है। एक वर्ग स्तर के एनोटेशन के रूप में या किसी भी @Configurationवर्ग में खेतों पर , या परीक्षण कक्षाओं के रूप में उपयोग किया जा सकता है @RunWithजो स्प्रिंगरनर हैं।

मोक्स टाइप या बीन नाम से पंजीकृत किया जा सकता है। संदर्भ में परिभाषित उसी प्रकार के किसी भी मौजूदा एकल बीन को मॉक द्वारा प्रतिस्थापित किया जाएगा, यदि कोई मौजूदा बीन परिभाषित नहीं किया गया है तो एक नया जोड़ा जाएगा।

जब @MockBeanकिसी फ़ील्ड पर उपयोग किया जाता है, साथ ही एप्लिकेशन संदर्भ में पंजीकृत किया जाता है, तो मॉक को भी फ़ील्ड में इंजेक्ट किया जाएगा।

Mockito.mock ()

इसका सिर्फ एक प्रतिनिधित्व है @Mock


5
आइए यह न भूलें कि @Mock को MockitoRunner या initMocks को मैन्युअल रूप से कॉल करने की आवश्यकता है।
फ्लोरियन शैटज़

4
के बीच फर्क सिर्फ इतना है @MockBeanऔर @Mockहै कि एक में नकली इंजेक्षन जाएगा Spring ApplicationContextऔर अन्य नहीं होगा?
डग

3
@ डउग आपने इसे अच्छी तरह से संक्षेप में बताया है, लेकिन यह याद रखने की जरूरत है कि मॉकबीन स्प्रिंग बूट का एक हिस्सा है
कॉमिवेंटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.