2013-08-20 8 views
102

साथ प्रतिक्रिया शरीर में स्ट्रिंग की जाँच करने के लिए मैं सरल एकीकरण परीक्षणmockMvc

@Test 
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception { 
    mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON) 
      .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}")) 
      .andDo(print()) 
      .andExpect(status().isBadRequest()) 
      .andExpect(?); 
} 

अंतिम पंक्ति में है मैं

और जवाब में मैं उम्मीद स्ट्रिंग के जवाब शरीर में प्राप्त स्ट्रिंग तुलना करना चाहते हैं:

MockHttpServletResponse: 
      Status = 400 
    Error message = null 
     Headers = {Content-Type=[application/json]} 
    Content type = application/json 
      Body = "Username already taken" 
    Forwarded URL = null 
    Redirected URL = null 

सामग्री(), शरीर() के साथ कुछ चाल का प्रयास किया लेकिन कुछ भी काम नहीं किया।

+11

बस सलाह के रूप में, 400 स्थिति कोड 'की तरह" कुछ के लिए वापस नहीं किया जाना चाहिए import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

और jsonPath संदर्भ से उपलब्ध है उपयोगकर्ता नाम पहले ही लिया गया है "'। यह 40 9 संघर्ष का अधिक होना चाहिए। –

+0

Thanx - इस परीक्षण का लक्ष्य ऐसी चीजों को निर्दिष्ट करना है। – abrasadera

उत्तर

50

@Sotirios Delimanolis जवाब काम करते हैं लेकिन मैं इस mockMvc अभिकथन के भीतर तार की तुलना के लिए देख रहा था

तो यहाँ यह

.andExpect(content().string("\"Username already taken - please try with different username\"")); 
बेशक

मेरे दावे विफल रहा है:

java.lang.AssertionError: Response content expected: 
<"Username already taken - please try with different username"> but was:<"Something gone wrong"> 

क्योंकि:

MockHttpServletResponse: 
      Body = "Something gone wrong" 

तो यह प्रमाण है कि यह काम करता है!

+8

बस अगर किसी के पास गतिशील आईडी वाले संदेश हैं, जैसे मैंने किया, तो यह जानकर मददगार है कि स्ट्रिंग() विधि एक हैमक्रिस्ट * युक्त स्ट्रिंग * मैचर भी स्वीकार करता है: '.andExpect (content()। स्ट्रिंग (युक्त स्ट्रिंग (" \ "उपयोगकर्ता नाम पहले ही लिया गया है"); – molholm

+3

सावधान रहें, यदि आप आरईएसटी (जैसे @ रीस्ट कंट्रोलर) 'सामग्री' के लिए स्प्रिंग एमवीसी का उपयोग कर रहे हैं हमेशा खाली रहता है और इसके बजाय प्रतिक्रियाओं को सत्यापित करने के लिए 'मॉडल' का उपयोग किया जाना चाहिए। –

+1

@ टिमबुथ, यह गलत है। अगर आपको ऐसी समस्या है तो आपको इसे एक प्रश्न के रूप में पोस्ट करना चाहिए क्योंकि यह निश्चित रूप से अपेक्षित व्यवहार नहीं है और न ही यह व्यवहार है मैंने अपने कोड में देखा है। – Paul

176

आप andReturn() पर कॉल कर सकते हैं और के रूप में सामग्री प्राप्त करने के लिए MvcResult ऑब्जेक्ट का उपयोग कर सकते हैं। नीचे देखें:

MvcResult result = mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON) 
      .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}")) 
      .andDo(print()) 
      .andExpect(status().isBadRequest()) 
      .andReturn(); 

String content = result.getResponse().getContentAsString(); 
// do what you will 
+10

सावधान रहें, यदि आप REST के लिए स्प्रिंग एमवीसी का उपयोग कर रहे हैं (उदा। @RestController) 'content' हमेशा खाली होता है और इसके बजाय प्रतिक्रियाओं को सत्यापित करने के लिए 'मॉडल' का उपयोग किया जाना चाहिए। –

+6

@ टिमबुथ क्या आप स्पष्टीकरण दे सकते हैं? एक '@ RestController' इंगित करता है कि सभी हैंडलर विधियों को '@ ResponseBody' के साथ निहित रूप से एनोटेट किया गया है। इसका मतलब है कि स्प्रिंग हैंडलर के रिटर्न वैल्यू को क्रमबद्ध करने और प्रतिक्रिया के लिए लिखने के लिए 'HttpMessageConverter' का उपयोग करेगा। आप शरीर को 'सामग्री() 'के साथ बहुत अधिक प्राप्त कर सकते हैं। –

+5

@SotiriosDelimanolis सही है ... मैं अभी देख रहा हूं JSON पर 'getContentAsString()' जो मेरे '@ RestController'-एनोटेटेड नियंत्रक से आया था। – Paul

31

वसंत MockMvc अब JSON के लिए सीधा समर्थन है। तो आप बस कहते हैं:

.andExpect(content().json("{'message':'ok'}")); 

और स्ट्रिंग तुलना के विपरीत, यह कहेंगे की तरह "लापता क्षेत्र xyz" या "संदेश कुछ उम्मीद 'ठीक है' 'NOK' मिल गया

इस विधि वसंत 4.1 में पेश किया गया था। ।

+1

क्या आप एक पूर्ण उदाहरण प्रदान कर सकते हैं? इस सुविधा का समर्थन करने के लिए 'ContentRequestMatchers' की भी आवश्यकता नहीं है? – Zarathustra

0
String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage() 

यह आपको प्रतिक्रिया का ढाँचा देना चाहिए। "उपयोगकर्ता नाम पहले ही ले लिया" आपके मामले में।

+0

wheres स्पष्टीकरण? इसकी आवश्यकता है या आप इसे इस प्रकार के उत्तर टिप्पणी में दे सकते हैं – user1140237

24

इन उत्तरों पढ़ना, मैं एक बहुत करने के लिए स्प्रिंग संस्करण 4.x संबंधित देख सकते हैं, मैं कर रहा हूँ विभिन्न कारणों से संस्करण 3.2.0 का उपयोग करना। तो content() से सीधे जेसन समर्थन जैसी चीज़ें संभव नहीं है।

मैंने पाया कि MockMvcResultMatchers.jsonPath का उपयोग करना वास्तव में आसान है और एक इलाज करता है। एक पोस्ट विधि का परीक्षण करने का एक उदाहरण यहां दिया गया है।

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

(org.springframework.test.web.servlet.result.MockMvcResultMatchers का उपयोग करना)

String expectedData = "some value"; 
mockMvc.perform(post("/endPoint") 
       .contentType(MediaType.APPLICATION_JSON) 
       .content(mockRequestBodyAsString.getBytes())) 
       .andExpect(status().isOk()) 
       .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData)); 

अनुरोध शरीर सिर्फ एक json स्ट्रिंग है, जो आप आसानी से एक वास्तविक json नकली डेटा फ़ाइल से लोड कर सकते हैं यदि आप चाहते थे, लेकिन मुझे लगता है कि यहाँ शामिल नहीं किया था के रूप में यह होता है सवाल से विचलित

वास्तविक json लौटे इस तरह दिख रही है |:

{ 
    "data":"some value" 
} 
4

स्प्रिंग सुरक्षा के @WithMockUser और hamcrest के containsString मिलान एक सरल और सुरुचिपूर्ण समाधान के लिए बनाता है:

@Test 
@WithMockUser(roles = "USER") 
public void loginWithRoleUserThenExpectUserSpecificContent() throws Exception { 
    mockMvc.perform(get("/index")) 
      .andExpect(status().isOk()) 
      .andExpect(content().string(containsString("This content is only shown to users."))); 
} 

More examples on github

1

से लिया वसंत का tutorial

mockMvc.perform(get("/" + userName + "/bookmarks/" 
      + this.bookmarkList.get(0).getId())) 
      .andExpect(status().isOk()) 
      .andExpect(content().contentType(contentType)) 
      .andExpect(jsonPath("$.id", is(this.bookmarkList.get(0).getId().intValue()))) 
      .andExpect(jsonPath("$.uri", is("http://bookmark.com/1/" + userName))) 
      .andExpect(jsonPath("$.description", is("A description"))); 

is से import static org.hamcrest.Matchers.*;

jsonPath उपलब्ध है पाया जा सकता है here

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