2014-06-13 8 views
12

में JSON के रूप में एक नकली वस्तु को कैसे भेजें I सामग्री प्रकार JSON के साथ MockMvc के माध्यम से नियंत्रक में एक नकली वस्तु भेजना चाहते हैं। लेकिन जब मैं क्रमानुसार करने कोशिश कर रहा हूँ नकली त्रुटि है:mockmvc

java.lang.UnsupportedOperationException: Expecting parameterized type, got interface org.mockito.internal.MockitoInvocationHandler. 
Are you missing the use of TypeToken idiom? 

मेरे कोड निम्न प्रकार है:

@Test 
public void testSomething(){ 

    String xyz = ""; 
    Integer i = 10; 
    SomeClass inst = mock(SomeClass.class, withSettings().serializable()); 
    when(inst.getProperty1()).then(xyz); 
    when(inst.getProperty2()).then(i); 

    Gson gson = new Gson(); 
    String json = gson.toJson(inst); // this is creating error 

    this.mockmvc.perform(put("/someUrl/").contentType(MediaType.JSON).content(json)).andExpect(status().isOk()); 
} 

कोई मुझे बता सकते हैं कि मैं क्या याद कर रहा हूँ?

+0

आप आप देख सकते हैं कि gson.toJson (Inst) एपीआई एक मज़ाक उड़ाया वस्तु संभाल कर सकते हैं SomeClass मजाक कर रहे हैं। मुझे लगता है कि इस मुद्दे को – vikeng21

+0

सही है, लेकिन एक नकली वस्तु को क्रमबद्ध करने का एक तरीका होना चाहिए अन्यथा नियंत्रक को सामग्री के रूप में नकली वस्तु भेजने का कोई तरीका नहीं होगा। अब एकमात्र तरीका नकली वस्तु के बजाय नकली वस्तु का उपयोग कर रहा है? – Sourabh

उत्तर

20

मेरा प्रस्ताव है कि आप अपने SomeClass कि getProperty1() और getProperty2() विधि के लिए जाना जाता है मूल्यों रिटर्न की एक stub बनाएँ: तुम वहाँ nulls को क्रमानुसार चाहते हैं वह भी के लिए एक समारोह है। SomeClass कैसे कार्यान्वित किया जाता है पर निर्भर करता है, आप या तो यह एक new उदाहरण सीधे बना सकते हैं, उपवर्ग और कुछ तरीकों को ओवरराइड, अगर यह एक अंतरफलक है एक गुमनाम आंतरिक वर्ग बनाने के लिए, आदि

@Test 
public void testSomething(){ 

    String xyz = ""; 
    Integer i = 10; 

    // alt 1: 
    SomeClass stub = new SomeClass(xyz, i); 

    // alt 2: 
    SomeClass stub = new StubSomeClass(xyz, i); // StubSomeClass extends SomeClass 

    // alt 3: 
    SomeClass stub = new SomeClass() { 
     @Override 
     String getProperty1() { 
      return xyz; 
     } 
     @Override 
     Integer getProperty2() { 
      return i; 
     } 
    } 

    Gson gson = new Gson(); 
    String json = gson.toJson(stub); 

    this.mockmvc.perform(put("/someUrl/") 
     .contentType(MediaType.APPLICATION_JSON).content(json)) 
     .andExpect(status().isOk()); 
} 
+0

Alt 3 के बारे में जाने का एक अच्छा तरीका है। चूंकि मैं एक मॉडल (एक बीन) का नकल करने की कोशिश कर रहा था, इसलिए मैं हमेशा चीजों को लौटने वाले ओवरर्सिंग गेटर्स का उपयोग कर सकता था। लेकिन मुझे लगता है कि यहां स्टब स्वयं एक नकली वस्तु है और मैं उस वस्तु पर व्यवहार और कॉल को सत्यापित करने में सक्षम नहीं हूं जो मेरा मुख्य उद्देश्य था। – Sourabh

+0

कोई MediaType.JSON नाम नहीं है। – Dims

+0

@Dims क्षमा करें, वह मूल प्रश्न से एक प्रतिलिपि/पेस्ट त्रुटि थी। [MediaType.APPLICATION_JSON] (http://docs.spring.io/spring-framework/docs/4.2.x/javadoc-api/org/springframework/http/MediaType.html#APPLICATION_JSON) सही नाम है। – matsev

5

भले ही यह संभव हो, एक JSON कनवर्टर को नकली ऑब्जेक्ट सबमिट करना उस ऑपरेशन को समर्पित एक इकाई परीक्षण मानता है: मॉक ऑब्जेक्ट में वास्तविक वर्ग से बहुत अधिक गुण और विधियां हो सकती हैं और क्रमबद्धता तक पहुंच सकती है वास्तव में अजीब परिणाम।

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

+0

समझ में आता है। इस प्रकार के कार्यान्वयन के लिए बीटीडब्ल्यू का मतलब है कि मुझे जीएसओएन उदाहरण का मज़ाक उड़ाया जाना चाहिए और फिर जेएसओएन() फ़ंक्शन को कार्यान्वित करना चाहिए?इसके अलावा मुझे लगता है कि अधिक समझ में आता है कि MockMvc के माध्यम से हम ब्राउज़र अनुरोध को दोहराने की कोशिश कर रहे हैं। चूंकि ब्राउजर ज्यादातर (बल्कि आराम से) जेसन के साथ काम करते हैं, जिसका मतलब है कि अगर मैं नकली को जेसन में परिवर्तित कर रहा हूं, तो यह तब भी हटा दिया जाएगा जब() और फिर() जिसके परिणामस्वरूप एक सादा जेसन होता है जिसके साथ इसका मज़ाक उड़ाया जाता है। – Sourabh

1

मैं एक निम्नलिखित तरीके से एक नकली वस्तु क्रमानुसार करने के लिए एक रास्ता मिला:

Gson gson = new GSon(); 
String json = gson.toJson(mockedObject, mockedObjectType.class); 

हालांकि मैं क्या कोशिश कर रहा था एक व्यर्थ था चूंकि जेसन को सभी मॉकिंग से हटा दिया जाएगा, मैंने टेस्ट() फ़ंक्शन में प्रदान किया है, जब ऑब्जेक्ट का पुनर्निर्माण किया जाएगा, उसके पास मॉकिंग का कोई मूल्य नहीं होगा और किसी भी फ़ंक्शन/प्रॉपर्टी के उपयोग के पहले उदाहरण पर NullPointerException फेंक देगा ।

संपादित करें:

Gson gson = new GsonBuilder().serializeNulls().create(); 
1

हम ने वही समस्या थी: जेसन को क्रमबद्ध ऑब्जेक्ट आउटपुट करने के लिए लॉगिंग स्टेटमेंट था। और इस उत्पादित त्रुटि के लिए यूनिट टेस्ट केस क्योंकि जीसन नकली ऑब्जेक्ट को क्रमबद्ध नहीं कर सका। यह बहिष्कार रणनीति है कि क्लास और प्रकार कक्षा के क्षेत्र serializing छोड़ देता है प्रदान करने के साथ हल किया गया था:

private final Gson gson = new GsonBuilder() 
    .setExclusionStrategies(new ExclusionStrategy() { 
    @Override 
    public boolean shouldSkipClass(Class<?> clazz) { 
     return clazz instanceof Class; 
    } 

    @Override 
    public boolean shouldSkipField(FieldAttributes field) { 
     return field.getDeclaredClass() == Class.class; 
    } 
}).create(); 
0

परीक्षण विन्यास में आपको कोई संदेश कनवर्टर जो स्ट्रिंग में किसी भी वस्तु की क्रमबद्धता का समर्थन करता है के साथ डिफ़ॉल्ट संदेश कनवर्टर लपेट कर सकते हैं।

package com.example; 

import org.apache.commons.io.IOUtils; 
import org.springframework.http.HttpInputMessage; 
import org.springframework.http.HttpOutputMessage; 
import org.springframework.http.MediaType; 
import org.springframework.http.converter.AbstractHttpMessageConverter; 
import org.springframework.http.converter.HttpMessageNotReadableException; 
import org.springframework.http.converter.HttpMessageNotWritableException; 

import java.io.IOException; 
import java.util.Arrays; 

public class MockObjectHttpMessageConverter extends AbstractHttpMessageConverter { 


    private final AbstractHttpMessageConverter primaryConverter; 

    public MockObjectHttpMessageConverter(AbstractHttpMessageConverter primaryConverter) { 
    this.primaryConverter = primaryConverter; 
    setSupportedMediaTypes(Arrays.asList(MediaType.ALL)); 
    } 

    @Override 
    protected boolean supports(Class clazz) { 
    return true; 
    } 

    @Override 
    protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { 
    throw new UnsupportedOperationException(); 
    } 

    @Override 
    protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { 
    try { 
     primaryConverter.write(o, MediaType.ALL, outputMessage); 
    } catch (Exception e) { 
     IOUtils.write(o.toString(), outputMessage.getBody()); 
    } 
    } 
} 

वसंत के संदर्भ एक्सएमएल पुट में:

<mvc:message-converters> 
    <bean class="com.example.MockObjectHttpMessageConverter"> 
     <constructor-arg> 
      <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter"> 
       <property name="gson"> 
        <bean class="com.google.gson.Gson" factory-bean="gsonBuilder" factory-method="create"/> 
       </property> 
      </bean> 
     </constructor-arg> 
    </bean> 
</mvc:message-converters> 
संबंधित मुद्दे