2015-09-04 12 views
33

मैं एक साधारण वसंत वेब एप्लिकेशन के लिए कुछ सरल यूनिट परीक्षण दिनचर्या लिख ​​रहा हूं। जब मैं किसी संसाधन के गेटटर विधि पर @JsonIgnore एनोटेशन जोड़ता हूं, परिणामी जेसन ऑब्जेक्ट में संबंधित जेसन तत्व शामिल नहीं होता है। तो जब मेरी यूनिट टेस्ट रूटीन परीक्षण करने की कोशिश करती है कि यह शून्य है (जो मेरे मामले के लिए अपेक्षित व्यवहार है, मैं नहीं चाहता कि पासवर्ड जेसन ऑब्जेक्ट में उपलब्ध हो), परीक्षण नियमित रूप से अपवाद में चलता है:परीक्षण कैसे करें यदि JSON पथ में कोई विशिष्ट तत्व शामिल नहीं है, या यदि तत्व मौजूद है तो यह शून्य है?

java.lang.AssertionError: No value for JSON path: $.password, exception: No results for path: $['password']

@Test 
public void getUserThatExists() throws Exception { 
    User user = new User(); 
    user.setId(1L); 
    user.setUsername("zobayer"); 
    user.setPassword("123456"); 

    when(userService.getUserById(1L)).thenReturn(user); 

    mockMvc.perform(get("https://stackoverflow.com/users/1")) 
      .andExpect(jsonPath("$.username", is(user.getUsername()))) 
      .andExpect(jsonPath("$.password", is(nullValue()))) 
      .andExpect(jsonPath("$.links[*].href", hasItem(endsWith("https://stackoverflow.com/users/1")))) 
      .andExpect(status().isOk()) 
      .andDo(print()); 
} 

मैं भी jsonPath() मौजूद है() जो समान अपवाद हो जाता है के साथ यह कोशिश की है:।

इस इकाई परीक्षा पद्धति मैंने लिखा, साथ 'पासवर्ड' क्षेत्र परीक्षण कर रहा है (nullValue()) विधि है यह बताते हुए कि पथ मौजूद नहीं है। मैं कुछ और कोड स्निपेट साझा कर रहा हूं ताकि पूरी स्थिति अधिक पठनीय हो जाए।

नियंत्रक विधि मैं परीक्षण कर रहा हूँ इस तरह दिखता है:

@RequestMapping(value="https://stackoverflow.com/users/{userId}", method= RequestMethod.GET) 
public ResponseEntity<UserResource> getUser(@PathVariable Long userId) { 
    logger.info("Request arrived for getUser() with params {}", userId); 
    User user = userService.getUserById(userId); 
    if(user != null) { 
     UserResource userResource = new UserResourceAsm().toResource(user); 
     return new ResponseEntity<>(userResource, HttpStatus.OK); 
    } else { 
     return new ResponseEntity<>(HttpStatus.NOT_FOUND); 
    } 
} 

मैं वसंत hateos संसाधन कोडांतरक उपयोग कर रहा हूँ इकाई परिवर्तित वस्तुओं संसाधन के लिए और यह मेरा संसाधन वर्ग है:

public class UserResource extends ResourceSupport { 
    private Long userId; 
    private String username; 
    private String password; 

    public Long getUserId() { 
     return userId; 
    } 

    public void setUserId(Long userId) { 
     this.userId = userId; 
    } 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @JsonIgnore 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

मैं समझें कि यह अपवाद क्यों प्राप्त कर रहा है, एक तरह से, परीक्षण सफल है कि इसे पासवर्ड फ़ील्ड नहीं मिला। लेकिन मैं क्या करना चाहता हूं, यह सुनिश्चित करने के लिए कि यह क्षेत्र मौजूद नहीं है, या यदि मौजूद है, तो इसमें शून्य मान शामिल है। इसे कैसे प्राप्त किया जा सकता है?

वहाँ ढेर अतिप्रवाह में एक ऐसी ही पोस्ट है: Hamcrest with MockMvc: check that key exists but value may be null

मेरे मामले में, क्षेत्र गैर विद्यमान रूप में अच्छी तरह हो सकता है।

<dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-core</artifactId> 
     <version>2.6.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-annotations</artifactId> 
     <version>2.6.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-databind</artifactId> 
     <version>2.6.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.jayway.jsonpath</groupId> 
     <artifactId>json-path</artifactId> 
     <version>2.0.0</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.jayway.jsonpath</groupId> 
     <artifactId>json-path-assert</artifactId> 
     <version>2.0.0</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.12</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.mockito</groupId> 
     <artifactId>mockito-all</artifactId> 
     <version>1.10.19</version> 
     <scope>test</scope> 
    </dependency> 

अग्रिम धन्यवाद:

रिकॉर्ड के लिए, इन मैं उपयोग कर रहा हूँ परीक्षण संकुल की संस्करण हैं।

[संपादित करें] अधिक सटीक होने के लिए, आपको एक इकाई के लिए एक परीक्षा लिखनी है जहां आप जानते हैं कि कुछ क्षेत्रों को शून्य या खाली होना चाहिए या यहां तक ​​कि अस्तित्व में नहीं होना चाहिए, और आप वास्तव में नहीं जाते कोड के माध्यम से यह देखने के लिए कि संपत्ति के शीर्ष पर एक जेसन इग्नोर जोड़ा गया है या नहीं। और आप अपने परीक्षण पास करना चाहते हैं, मैं यह कैसे कर सकता हूं।

कृपया मुझे यह बताने में संकोच न करें कि यह बिल्कुल व्यावहारिक नहीं है, लेकिन अभी भी जानना अच्छा होगा।

[संपादित करें] ऊपर परीक्षण निम्नलिखित पुराने json-पथ निर्भरता के साथ सफल होता है:

<dependency> 
     <groupId>com.jayway.jsonpath</groupId> 
     <artifactId>json-path</artifactId> 
     <version>0.9.1</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.jayway.jsonpath</groupId> 
     <artifactId>json-path-assert</artifactId> 
     <version>0.9.1</version> 
     <scope>test</scope> 
    </dependency> 

[संपादित करें] वसंत के json के प्रलेखन पढ़ने के बाद एक QuickFix कि jayway.jasonpath के नवीनतम संस्करण के साथ काम करता मिला पथ matcher।

.andExpect(jsonPath("$.password").doesNotExist()) 
+0

आपके अंतिम "संपादन" के लिए धन्यवाद। '.doesNotExist() 'मैं जो खोज रहा था वह था। – James

उत्तर

65

मैं नए संस्करण के साथ एक ही समस्या थी। मुझे लगता है कि doNotExist() फ़ंक्शन यह सत्यापित करेगा कि कुंजी परिणाम में नहीं है:

.andExpect(jsonPath("$.password").doesNotExist()) 
+1

है कि मैं क्या किया में वर्णित यह काम कर रहा, मेरे सवाल की अंतिम पंक्ति को देखो। [सवाल पिछले 14:55 पर पर \t सितं, 4 '15 संपादित] –

+1

अगर आप AssertJ का उपयोग (जैसेएक स्प्रिंग बूट ऐप में) यह जांचने का तरीका है 'assertThat (this.json.write (इकाई))। नहीं हैटहेज जेसनपाथवेल्यू ("@। कील"); ' –

2

@JsonIgnore अपेक्षा के अनुरूप, json उत्पादन में पासवर्ड का निर्माण नहीं कर रहा है, तो कैसे आप कुछ है कि आप स्पष्ट रूप से उत्पादन से छोड़कर कर रहे हैं परीक्षण करने के लिए उम्मीद कर सकता है?

लाइन:

.andExpect(jsonPath("$.property", is("some value"))); 

या यहां तक ​​कि एक परीक्षण है कि संपत्ति शून्य है:

.andExpect(jsonPath("$.property").value(IsNull.nullValue())); 

की तरह एक json के अनुरूप:

{ 
... 
"property": "some value", 
... 
} 

जहां महत्वपूर्ण हिस्सा है

: बाईं ओर, कि "संपत्ति" का अस्तित्व

इसके बजाय, @JsonIgnore बिल्कुल उत्पादन में porperty उत्पादन नहीं कर रहा है, तो आप उम्मीद नहीं कर सकते यह नहीं परीक्षण में है और न ही उत्पादन उत्पादन में। यदि आप आउटपुट में संपत्ति नहीं चाहते हैं, तो यह ठीक है, लेकिन आप इसे परीक्षण में उम्मीद नहीं कर सकते हैं।

Mapper.mapPersonToRest(User user) {//exclude the password} 

और फिर अपने: आप इसे खाली उत्पादन में (prod और परीक्षण में दोनों) चाहते हैं तो आप बीच कि json वस्तु के लिए संपत्ति के मूल्य से गुजर नहीं है में एक स्थिर मैपर विधि बनाना चाहते हैं तरीका होगा:

@RequestMapping(value="https://stackoverflow.com/users/{userId}", method= RequestMethod.GET) 
public ResponseEntity<UserResource> getUser(@PathVariable Long userId) { 
    logger.info("Request arrived for getUser() with params {}", userId); 
    User user = Mapper.mapPersonToRest(userService.getUserById(userId)); 
    if(user != null) { 
     UserResource userResource = new UserResourceAsm().toResource(user); 
     return new ResponseEntity<>(userResource, HttpStatus.OK); 
    } else { 
     return new ResponseEntity<>(HttpStatus.NOT_FOUND); 
    } 
} 

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

पीएस बेशक पासवर्ड डीबी पर क्रिप्ट किया गया है, है ना? ;)

+0

हां जेसन इग्नोर उम्मीद के अनुसार प्रदर्शन कर रहा है। तो कुछ क्षेत्रों में जेसन इग्नोर के साथ इकाइयों की जांच के लिए सबसे अच्छा अभ्यास क्या होगा। इस मान लें, तो आप एक परीक्षण लिखना चाहते हैं कहते हैं, तुम्हें पता है जो (या यहां तक ​​मौजूद नहीं होना चाहिए) फ़ील्ड खाली या शून्य होना चाहिए, लेकिन आप स्रोत कोड खोलने के लिए और अगर वहाँ वास्तव में है उन पर एक JsonIgnore एनोटेशन को पढ़ने के लिए नहीं जा रहे हैं। और जाहिर है कि आप अपने परीक्षण को पास करना चाहते हैं, अपवाद के साथ असफल नहीं। ओह और पासवर्ड धोया गया है। यह महत्वपूर्ण नहीं है, सिर्फ एक परीक्षण परियोजना है। –

+0

आप क्या करना चाहते हैं यह ध्यान रखना है कि ऑब्जेक्ट UserResource पासवर्ड नहीं लौटा रहा है, है ना? आइए मान लें कि आपके पास नया UserResourceAsm()। ToResource (उपयोगकर्ता) उपयोगकर्ता को वापस कर रहा है, है ना? इस मामले में, आपको स्प्रिंगएमवीसी स्तर पर परीक्षण नहीं करना चाहिए, लेकिन केवल एक सामान्य यूनिट टेस्ट करें जो उपयोगकर्ता की जांच कर रहा है .getPassword() शून्य है। उम्मीद है कि यह स्पष्ट है! – Paolof76

+0

मैंने आपको समझने में मदद करने के लिए एक उदाहरण जोड़ा जो मेरा मतलब है। मुझे देखने दो कि क्या आपको अधिक संदेह हैं – Paolof76

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