2014-07-01 7 views
8

से मैक्स पढ़ने के लिए मैं जर्सीटेस्ट के साथ एक रिसोर का परीक्षण करना चाहता हूं। मैं निम्नलिखित परीक्षण बनाया है:फोर्स जर्सी जर्सीटेस्ट

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:testApplicationContext.xml") 
public class ResourceTest extends JerseyTest 
{ 
    @Configuration 
    public static class Config 
    { 
     @Bean 
     public AObject aObject() 
     { 
      return mock(AObject.class); 
     } 
    } 

    @Autowired 
    public AObject _aObject; 

    @Test 
    public void testResource() 
    { 
     // configouring mock _aObject 

     Response response = target("path"); 
     Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); 
    } 


    @Override 
    protected Application configure() 
    { 
     return new ResourceConfig(Resource.class).property("contextConfigLocation", "classpath:testApplicationContext.xml"); 
    } 
} 

मेरे संसाधन भी @Autowired टिप्पणी के साथ एक AObject संदर्भ है।

मेरी समस्या यह है कि मेरा JerseyTest और Resource (जिसे परीक्षण द्वारा कॉन्फ़िगर किया गया है) में मॉक ऑब्जेक्ट के लिए अलग-अलग उदाहरण हैं। कंसोल में मैं देखता हूं कि testApplicationContext.xml परीक्षण के लिए एक बार और संसाधन के लिए दो बार लोड किया जाता है।

मैं उसी मॉक का उपयोग करने के लिए जर्सी को कैसे मजबूर कर सकता हूं?

उत्तर

15

जर्सी-spring3 (संस्करण 2.9.1) पुस्तकालय डिबगिंग के बाद ऐसा लगता है कि समस्या SpringComponentProvider.createSpringContext में निहित है

private ApplicationContext createSpringContext() { 
    ApplicationHandler applicationHandler = locator.getService(ApplicationHandler.class); 
    ApplicationContext springContext = (ApplicationContext) applicationHandler.getConfiguration().getProperty(PARAM_SPRING_CONTEXT); 
    if (springContext == null) { 
     String contextConfigLocation = (String) applicationHandler.getConfiguration().getProperty(PARAM_CONTEXT_CONFIG_LOCATION); 
     springContext = createXmlSpringConfiguration(contextConfigLocation); 
    } 
    return springContext; 
} 

यह जाँच करता है एक संपत्ति नाम "contextConfig" आवेदन गुण में मौजूद रहने पर और यदि नहीं, तो यह वसंत अनुप्रयोग संदर्भ शुरू करता है। भले ही आप अपने परीक्षण में वसंत आवेदन संदर्भ प्रारंभ, जर्सी एक और संदर्भ बना सकते हैं और बजाय का उपयोग करें कि एक होगा। इसलिए हमें जर्सी एप्लिकेशन क्लास में हमारे परीक्षणों से एप्लिकेशन कॉन्टेक्स्ट को किसी भी तरह से पास करना होगा।

@ContextConfiguration(locations = "classpath:jersey-spring-applicationContext.xml") 
public abstract class JerseySpringTest 
{ 
    private JerseyTest _jerseyTest; 

    public final WebTarget target(final String path) 
    { 
     return _jerseyTest.target(path); 
    } 

    @Before 
    public void setup() throws Exception 
    { 
     _jerseyTest.setUp(); 
    } 

    @After 
    public void tearDown() throws Exception 
    { 
     _jerseyTest.tearDown(); 
    } 

    @Autowired 
    public void setApplicationContext(final ApplicationContext context) 
    { 
     _jerseyTest = new JerseyTest() 
     { 
      @Override 
      protected Application configure() 
      { 
       ResourceConfig application = JerseySpringTest.this.configure(); 
       application.property("contextConfig", context); 

       return application; 
      } 
     }; 
    } 

    protected abstract ResourceConfig configure(); 
} 

ऊपर वर्ग हमारे परीक्षणों से आवेदन संदर्भ लेने के लिए और कॉन्फ़िगर ResourceConfig को इसे पारित ताकि SpringComponentProvider जर्सी के लिए एक ही आवेदन संदर्भ वापस आ जाएगी होगा: समाधान निम्नलिखित है। जर्सी विशिष्ट वसंत विन्यास को शामिल करने के लिए हम जर्सी-वसंत-अनुप्रयोगकॉन्टेक्स्ट.एक्सएमएल का भी उपयोग करते हैं।

हम जर्सीटेस्ट से उत्तराधिकारी नहीं हो सकते क्योंकि यह परीक्षण आवेदन संदर्भ शुरू होने से पहले निर्माता में एप्लिकेशन को प्रारंभ करता है।

अब आप testContext.xml में उदाहरण

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:testContext.xml") 
public class SomeTest extends JerseySpringTest 
{ 
    @Autowired 
    private AObject _aObject; 

    @Test 
    public void test() 
    { 
      // configure mock _aObject when(_aObject.method()).thenReturn() etc... 

     Response response = target("api/method").request(MediaType.APPLICATION_JSON).get(); 
     Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); 
    } 

    @Override 
    protected ResourceConfig configure() 
    { 
     return new ResourceConfig(MyResource.class); 
    } 
} 

के लिए अपने परीक्षण बनाने के लिए आदेश में एक नकली AObject इंजेक्षन करने के लिए निम्नलिखित परिभाषा जोड़ने इस आधार वर्ग का उपयोग कर सकते हैं।

<bean class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="com.yourcompany.AObject" /> 
</bean> 
+1

महान जवाब! धन्यवाद –

+0

आपको यह उत्तर यह मेरी समस्याओं को हल करती है जर्सी परीक्षण ढांचे और वसंत-परीक्षण के साथ एकीकरण के परीक्षण विकसित करने के लिए बहुत बहुत धन्यवाद। विशेष रूप से मेरी समस्या एक ही ApplicationContext में परीक्षण निष्पादन के दौरान नकली वस्तुओं का निर्देश देने की थी। सबको धन्यवाद, – bifulcoluigi

1

मैं @Grigoris से जवाब https://stackoverflow.com/a/24512682/156477 काम कर रहा है, हालांकि यह क्यों हो रहा है के लिए अपने विवरण सही है नहीं मिल सका।

अंत में मैं नीचे दिए गए दृष्टिकोण के लिए गया जो नकली वस्तु को सम्मिलित करने के लिए एक विशेष सेटटर का खुलासा करता है। ऊपर दृष्टिकोण के रूप में 'साफ़', लेकिन लायक apiProvider मैं तो नकली करना चाहता था उजागर की दुविधा मैं कुछ परीक्षण लिख सकता है ..

public MyAPITest extends JerseyTest { 

    // Declare instance of the API I want to test - this will be instantiated in configure() 
    MyAPI myAPI; 

    @Override 
    protected ResourceConfig configure() 
    { 
     MockitoAnnotations.initMocks(this); 
     myAPI = new MyAPI(); 

     ResourceConfig resourceConfig = new ResourceConfig(); 
     resourceConfig.register(MyAPI).property("contextConfig", new ClassPathXmlApplicationContext("classpath:spring.testHarnessContext.xml")); 
     return resourceConfig; 
    } 

    @Mock 
    private MyAPIProvider mockAPIProvider; 

    @Before 
    public void before() { 
     myAPI.setMockProvider(mockAPIProvider); 
    } 


    @Test 
    public void test() { 

     // I can now define the mock behaviours and call the API and validate the outcomes 
     when(mockAPIProvider....) 
     target().path("....)    
    } 
} 
0

अगर कोई जर्सी v1 के लिए केविन से समाधान https://stackoverflow.com/a/40591082/4894900 में रुचि रखता है के रूप में नहीं :

public MyAPITest extends JerseyTest { 

    @InjectMocks 
    MyAPI myAPI; 

    @Mock 
    MyApiService myApiService; 

    @Override 
    protected AppDescriptorconfigure() 
    { 
     MockitoAnnotations.initMocks(this); 

     ResourceConfig rc = new DefaultResourceConfig(); 
     rc.getSingletons().add(myAPI); 

     return new LowLevelAppDescriptor.Builder(rc).contextPath("context").build(); 
    } 

    @Test 
    public void test() { 
     // I can now define the mock behaviours 
     when(myApiService...) 

     WebResource webResource = resource().path("mypath"); 
     ClientResponse result = webResource.get(ClientResponse.class);    
    } 
}