स्प्रिंगबूटटेस्ट के साथ मॉकमबैक्स का उपयोग करने और वेबमेकटेस्ट का उपयोग करने के बीच अंतर


98

मैं स्प्रिंग बूट के लिए नया हूं और यह समझने की कोशिश कर रहा हूं कि स्प्रिंगबूट में परीक्षण कैसे काम करता है। मैं थोड़ा उलझन में हूँ कि निम्नलिखित दो कोड स्निपेट में क्या अंतर है:

कोड स्निपेट 1:

@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerApplicationTest {
    @Autowired    
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}

यह परीक्षण @WebMvcTestएनोटेशन का उपयोग करता है, जो मुझे लगता है कि फीचर स्लाइस परीक्षण के लिए है और केवल एक वेब एप्लिकेशन के एमवीसी परत का परीक्षण करता है।

कोड स्निपेट 2:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
    mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}

यह परीक्षण @SpringBootTestएनोटेशन और ए का उपयोग करता है MockMvc। तो यह कोड स्निपेट 1 से कैसे अलग है? यह अलग तरीके से क्या करता है?

संपादित करें: कोड स्निपेट 3 जोड़ना (इसे स्प्रिंग प्रलेखन में एकीकरण परीक्षण के उदाहरण के रूप में पाया गया)

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
public class HelloControllerIT {
    
    @LocalServerPort private int port;
    private URL base;
    
    @Autowired private TestRestTemplate template;
    
    @Before public void setUp() throws Exception {
        this.base = new URL("http://localhost:" + port + "/");
    }
    
    @Test public void getHello() throws Exception {
        ResponseEntity < String > response = template.getForEntity(base.toString(), String.class);
        assertThat(response.getBody(), equalTo("Greetings from Spring Boot!"));
    }
}

जवाबों:


89

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

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

डॉक्टर को पढ़ने से आपको भी मदद मिलेगी।


जवाब देने के लिए बहुत बहुत धन्यवाद !! इसलिए अगर मैं आपको सही तरीके से समझूं, तो इसका क्या मतलब है कि दोनों कोड स्निपेट आवेदन के केवल एमवीसी भाग का परीक्षण करते हैं। लेकिन टोड स्निपेट 1 पूर्ण एप्लिकेशन संदर्भ को लोड करता है जबकि कोड स्निपेट 2 केवल नियंत्रक को स्कैन करता है। क्या ये सही है? क्या कोड स्निपेट 1 को नियंत्रक का परीक्षण करने के लिए एक इकाई परीक्षण माना जा सकता है?
रेवांश

1
नहीं, यह सही नहीं है। SpringBootTestअपना पूरा ऐप लोड कर रहा है (कुछ विस्तार के लिए, डिफ़ॉल्ट रूप से यह एम्बेडेड कंटेनर को शुरू नहीं करेगा यदि कोई उपलब्ध है, तो वही है webEnvironmentजो इसके लिए है)। मैं यह नहीं कहूंगा कि @SpringBootTestनियंत्रक की एक इकाई परीक्षण है लेकिन वास्तव में अधिक एकीकरण परीक्षण है। WebMvcTestवास्तव में आपके नियंत्रक की एक इकाई परीक्षा इस अर्थ में होती है कि यदि उसमें निर्भरता है, तो आपको उन्हें स्वयं प्रदान करना होगा (या तो किसी तरह का एक विन्यास या मॉक)।
स्टीफन निकोल

फिर से जवाब देने के लिए धन्यवाद। मैंने प्रश्न संपादित किया है और कोड स्निपेट 3 जोड़ा है। आपने उल्लेख किया है कि @SpringBootTest एनोटेशन का उपयोग एकीकरण परीक्षण के लिए अधिक किया जाता है। मेरा मानना ​​है कि स्निपेट 3 इसका प्रदर्शन करता है। तो अगर Snippet 3 में एकीकरण परीक्षण किया जाता है तो Snippet 2 क्या करता है? स्निपेट 2 में स्प्रिंगबूटेस्ट एनोटेशन और मॉक एनवायरनमेंट का उपयोग किया गया है (wenEnvironment विशेषता का डिफ़ॉल्ट मान)। इसके अलावा, स्निपेट 3 एम्बेडेड सर्वर को शुरू करता है और वास्तव में HTTP कॉल करता है जबकि स्निपेट 2 ऐसा नहीं करता है। तो इसे देखते हुए, कैंट स्निपेट 2 को एक यूनिट टेस्ट माना जाए?
रेवांश

4
मुझे यकीन नहीं है कि हम इसे यहां से सुलझा लेंगे। शायद गटर? जो चीज आपको लगातार याद आ रही है, वह यह है कि एप्लिकेशन संदर्भ जो बनाते हैं SpringBootTestऔर WebMvcTestबनाते हैं वे काफी भिन्न होते हैं। पूर्व में आपका WHOLE ऐप लोड होता है और सभी ऑटो-कॉन्फ़िगरेशन को सक्षम करता है जबकि बाद वाला केवल स्प्रिंग Mvc को सक्षम करता है और कुछ भी स्कैन नहीं करता है HelloController। यह सब इस बात पर निर्भर करता है कि एक इकाई परीक्षण से आपका क्या मतलब है। लेकिन यही फर्क है।
स्टीफन निकोल

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

71

@SpringBootTest एनोटेशन स्प्रिंग बूट को एक मुख्य कॉन्फ़िगरेशन वर्ग (उदाहरण के लिए @SpringBootApplication के साथ एक) के लिए जाने के लिए कहता है, और स्प्रिंग एप्लिकेशन संदर्भ शुरू करने के लिए इसका उपयोग करें। SpringBootTest पूरा आवेदन लोड करता है और सभी बीन्स को इंजेक्ट करता है जो धीमा हो सकता है।

@WebMvcTest - नियंत्रक परत के परीक्षण के लिए और आपको मॉक ऑब्जेक्ट्स का उपयोग करके आवश्यक शेष निर्भरता प्रदान करने की आवश्यकता है।

आपके संदर्भ के लिए नीचे कुछ अधिक टिप्पणियां हैं।

एप्लिकेशन के परीक्षण स्लाइस कभी-कभी आप पूरे एप्लिकेशन को ऑटो-कॉन्फ़िगर करने के बजाय एक सरल "स्लाइस" एप्लिकेशन का परीक्षण करना चाहेंगे। स्प्रिंग बूट 1.4 ने 4 नए परीक्षण एनोटेशन पेश किए:

@WebMvcTest - for testing the controller layer
@JsonTest - for testing the JSON marshalling and unmarshalling
@DataJpaTest - for testing the repository layer
@RestClientTests - for testing REST clients

अधिक जानकारी के लिए देखें: https://spring.io/guides/gs/testing-web/


यहां स्पिंग बूट संदर्भ की एक कड़ी है - टेस्ट ऑटो-कॉन्फ़िगरेशन एनोटेशन । यहाँ सूचीबद्ध केवल चार @ roshankumar-mutha से अधिक हैं। आरंभ किए गए गाइड का लिंक इन स्लाइस को गहराई से कवर नहीं करता है।
जॉर्ज पेंटाज़ ने

15

एमवीसी परीक्षणों का उद्देश्य केवल आपके आवेदन के नियंत्रक टुकड़े को कवर करना है। HTTP अनुरोधों और प्रतिक्रियाओं का मज़ाक उड़ाया जाता है ताकि वास्तविक कनेक्शन न बनें। दूसरी ओर, जब आप उपयोग करते हैं @SpringBootTest, तो वेब एप्लिकेशन संदर्भ के लिए सभी कॉन्फ़िगरेशन लोड किए जाते हैं और कनेक्शन वास्तविक वेब सर्वर से गुजर रहे हैं। उस स्थिति में, आप MockMvcबीन का उपयोग नहीं करते हैं, लेकिन RestTemplateइसके बजाय एक मानक (या नया विकल्प TestRestTemplate)।

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

इसका मतलब यह नहीं है कि आप मोक्स का उपयोग नहीं कर सकते हैं @SpringBootTest; यदि आप एक एकीकरण परीक्षण लिख रहे हैं, तो यह अभी भी आवश्यक हो सकता है। किसी भी मामले में, इसका उपयोग केवल एक साधारण नियंत्रक इकाई परीक्षण के लिए नहीं करना बेहतर है।

source - स्प्रिंग बूट के साथ लर्निंग माइक्रोसर्विसेस


4
मुझे समझ नहीं आ रहा है कि यह उत्तर क्यों दिया गया है .. जब आप उपयोग करते हैं @SpringBootTest, तब तक एक वास्तविक वेब सर्वर शुरू नहीं होता है जब तक कि आपके पास भी webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT(या DEFINED_PORT) और कनेक्शन वास्तविक वेब सर्वर के माध्यम से नहीं जाते हैं। के लिए डिफ़ॉल्ट @SpringBootTestहै WebEnvironment.MOCK
कोरे तुगे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.