2012-11-20 27 views
17

के साथ काम नहीं करता है मेरे पास एक डमी रिसोर्स क्लास और डमी टाइटेट फ़ाइल है, और एक टेस्ट क्लास टेस्टडमी रिसोर्स नीचे है, लेकिन मॉक ऑब्जेक्ट DummyResource dr = mock(DummyResource.class) केवल तभी काम करता है जब मैं एक सामान्य श्रेणी के अंदर कन्स्ट्रक्टर को कॉल करता हूं , जब इसे किसी अज्ञात वर्ग में बुलाया जाता है, तो यह मॉक ऑब्जेक्ट का उपयोग करने के बजाय वास्तविक कन्स्ट्रक्टर को कॉल कर रहा है।कबूतर के माध्यम से पावरमॉक मॉकिंग कन्स्ट्रक्टर() अज्ञात वर्ग

संस्करण:

powermock 1.4.12 mockito 1.9.0 JUnit 4.8.2

DummyTarget.java:

import java.io.IOException; 
import java.io.OutputStream; 

import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.StreamingOutput; 


public class DummyTarget { 
    public StreamingOutput testMocking() { 
     return new StreamingOutput() { 
      @Override 
      public void write(OutputStream arg0) throws IOException, WebApplicationException { 
       new DummyResource(); 
      } 
     }; 
    } 
} 

DummyResource.java:

package com.smin.dummy; 

public class DummyResource { 
    public DummyResource() { 
     System.out.println("mock failure"); 
    } 
} 

TestDummyResource.java:

package com.smin.dummy; 

import static org.mockito.Mockito.mock; 

import java.io.IOException; 

import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.StreamingOutput; 

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({DummyResource.class,DummyTarget.class}) 
public class TestDummyResource { 

    @Before 
    public void setUp() throws Exception { 
     DummyResource dr = mock(DummyResource.class); 
     PowerMockito.whenNew(DummyResource.class).withNoArguments().thenReturn(dr); 
    } 

    @Test 
    public void testMocked() throws WebApplicationException, IOException { 
     new DummyResource(); // it uses the mocked object dr here, 
          //doesn't print "mock failure" 
     StreamingOutput sop = new DummyTarget().testMocking(); 
     sop.write(null);  // it calls DummyResource's constructor, 
          // prints ""mock failure"" here 
    } 
} 

उत्तर

10

ऐसा लगता है कि एक अज्ञात वर्ग कक्षा के पैकेज का उत्तराधिकारी हो सकता है जो इसे परिभाषित करता है। आप PrepareForTest की वाइल्डकार्ड प्रपत्र कोशिश कर सकते हैं? यदि वह काम नहीं करता है

@PrepareForTest("com.smin.dummy.*") 

, आप बन्दूक PrepareEverythingForTest एनोटेशन की कोशिश कर सकते।

+1

तैयार करें सब कुछ फॉरटेस्ट को चलाने के लिए उम्र लगती है। – Shengjie

+2

बिल्कुल सही, एपीआई को छोड़कर इस पोस्ट के बाद से बदल सकता है। '@PrepareForTest (पूरी तरह से योग्यता नाम =" com.smin.dummy। * ")' –

+0

@Brian लिंक ** मृत ** –

31

आप वर्ग निर्माता, वर्ग नहीं है, जिस पर निर्माता कहा जाता है, बुला तैयार किया है की जरूरत है आप को ठीक करना चाहिए निम्नलिखित:

@PrepareForTest(DummyTarget.class) 

अधिक जानकारी के लिए this पृष्ठ देखें।

+0

मेरे मामले वास्तव में अधिक जटिल है मदद की, निर्माता एक गुमनाम कक्षा में कहा जाता है जहां है भी @PrepareForTest में घोषित अज्ञात वर्ग अभी भी काम नहीं करता है। – Shengjie

+0

यह बुरा है, मुझे यकीन नहीं है कि अज्ञात वर्ग में निर्माता को नकल करने के लिए यह संभव है (PowerMock का उपयोग करके)। यदि आप स्रोत बदल सकते हैं तो आप इसे काम करने में सक्षम हो सकते हैं यदि आप इसे किसी निजी श्रेणी में बदलते हैं। – zbrunson

+0

मैंने उपरोक्त कोड को अपडेट किया है, अगर कोई अज्ञात वर्ग में कन्स्ट्रक्टर कहलाता है तो क्या कोई कामकाज है? – Shengjie

8

असल में, आपको उस वर्ग की परीक्षा के लिए तैयार करना है जो कन्स्ट्रक्टर कॉल करता है, न कि जिस श्रेणी पर निर्माता को बुलाया गया था। https://github.com/jayway/powermock/wiki/MockConstructor देखें।

आपके मामले में, आप @PrepareForTest (DummyTarget.class) का उपयोग करना चाहिए

+2

यह वास्तव में सही उत्तर है, ऊपर जैसा नहीं। – user590849

+0

मेरे लिए काम किया। धन्यवाद। – defactodeity

0

मैं एक ही समस्या थी, और whenNew पूरी तरह से योग्य नाम के साथ उपयोग करने के साथ यह संकल्प लिया। आपके मामले में एक आंतरिक गुमनाम वर्ग की पूरी तरह से योग्य नाम है:

DummyTarget.class + "$1" 

ताकि आप उस वर्ग के एक नकली बनाना चाहिए:

DummyResource dr = mock(Class.forName(DummyTarget.class + "$1")); 

और यह आपके लिए काम करेंगे।

इसके अलावा, भूल नहीं है DummyTarget वर्ग तैयार करने के लिए:

@PrepareForTest(DummyTarget.class) 

आशा है कि यह =]

+0

आंशिक रूप से काम किया। मैं अज्ञात वर्ग का एक नकली वस्तु बनाने में सक्षम हूं। इसे वास्तविक कोड से जोड़ने में भी सक्षम है। लेकिन वस्तु हमेशा शून्य है। –