एक JAX-RS वेब सेवा का परीक्षण?


84

मैं वर्तमान में JAX-RS (RESTful Web Services के लिए जावा एपीआई) आधारित वेब सेवा के लिए स्वचालित परीक्षण बनाने के तरीके खोज रहा हूँ ।

मुझे मूल रूप से इसे कुछ इनपुट भेजने और सत्यापित करने की आवश्यकता है कि मुझे अपेक्षित प्रतिक्रियाएं मिलें। मैं JUnit के माध्यम से ऐसा करना पसंद करूंगा, लेकिन मुझे यकीन नहीं है कि यह कैसे हासिल किया जा सकता है।

अपनी वेब-सेवाओं का परीक्षण करने के लिए आप किस दृष्टिकोण का उपयोग करते हैं?

अद्यतन: जैसा कि entzik ने बताया, व्यवसाय तर्क से वेब सेवा को डिकूप करना मुझे व्यावसायिक तर्क का परीक्षण करने की अनुमति देता है। हालाँकि, मैं सही HTTP स्थिति कोड आदि के लिए भी परीक्षण करना चाहता हूं।


6
अच्छा सवाल - हालाँकि मैं कहूँगा कि यदि आप HTTP पर परीक्षण कर रहे हैं तो यह मुझे बताता है कि यह एकीकरण परीक्षण है।
टॉम डेयरिंग

टॉम। तुम पूरी तरह ठीक हो। हमें इसके लिए डमी HTTP एमुलेटर / लाइटवेट कंटेनर इंजेक्ट करना चाहिए। नोड.जेएस में विश्व सुपरसर्स्ट इसे बनाता है। आप एक्सप्रेस.जेएस का अनुकरण कर सकते हैं।
फ्रात कृष्ण

जवाबों:


34

जर्सी एक महान प्रतिष्ठित क्लाइंट एपीआई के साथ आता है जो लेखन इकाई परीक्षणों को वास्तव में आसान बनाता है। जर्सी के साथ जहाज बनाने वाले उदाहरणों में इकाई परीक्षण देखें। आप अपाचे कैमल में आरईएसटी समर्थन का परीक्षण करने के लिए इस दृष्टिकोण का उपयोग करते हैं, यदि आप रुचि रखते हैं तो परीक्षण के मामले यहां हैं


6
पुन: अब बुरा लिंक आप जर्सी / नमूनों में उल्लिखित उदाहरण पा सकते हैं जो इकाई परीक्षण दिखाते हैं, मूल रूप से वेब संसाधनों का उपभोग करने के लिए जर्सी के उपभोक्ताओं का उपयोग करके। download.java.net/maven/2/com/sun/jersey/samples/bookstore/…
rogerdpack

2
यह परियोजना GitHub पर है, src / test फ़ोल्डर में परीक्षण खोजें: github.com/jersey/jersey/tree/master/examples/bookstore-webapp
Venkat

2
मुझे इस उत्तर पर संदेह नहीं है, लेकिन मुझे यह अविश्वसनीय रूप से मज़ेदार लगता है कि जर्सी हमेशा एक JAX-RS वार्तालाप में अपना रास्ता बनाती है, जब कुछ मामलों में (WebSphere, दुर्भाग्य से, सटीक होना) यह अनुपलब्ध है और सभी स्वीकार्य उत्तरों का 99% प्रदान करता है स्टैक ओवरफ्लो नल और शून्य पर।

26

आप REST एश्योर्ड को आज़मा सकते हैं जो REST सेवाओं का परीक्षण करने और जावा में प्रतिक्रिया को मान्य करने के लिए बहुत आसान बनाता है (JUnit या TestNG का उपयोग करके)।


1
मैंने आपकी पोस्ट को वोट किया क्योंकि लाइब्रेरी अच्छी लग रही थी, लेकिन उन्हें यकीन है कि बहुत सारे निर्भर जार का उपयोग किया जाता है ...
पेरी तेव

17

जैसा कि जेम्स ने कहा; जर्सी के लिए अंतर्निहित परीक्षण ढांचा है। एक सरल हैलो दुनिया का उदाहरण इस प्रकार हो सकता है:

मावेन एकीकरण के लिए pom.xml। जब आप चलाने के mvn test। चौखटे एक ख़ाकी कंटेनर शुरू करते हैं। आप बदलती निर्भरता के माध्यम से जेट्टी या टॉमकैट का उपयोग कर सकते हैं।

...
<dependencies>
  <dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.16</version>
  </dependency>

  <dependency>
    <groupId>org.glassfish.jersey.test-framework</groupId>
    <artifactId>jersey-test-framework-core</artifactId>
    <version>2.16</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>2.16</version>
    <scope>test</scope>
  </dependency>
</dependencies>
...

ExampleApp.java

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class ExampleApp extends Application {

}

HelloWorld.java

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
public final class HelloWorld {

    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHelloWorld() {

        return "Hello World!";
    }
}

HelloWorldTest.java

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.core.Application;
import static org.junit.Assert.assertEquals;

public class HelloWorldTest extends JerseyTest {

    @Test
    public void testSayHello() {

        final String hello = target("hello").request().get(String.class);

        assertEquals("Hello World!", hello);
    }

    @Override
    protected Application configure() {

        return new ResourceConfig(HelloWorld.class);
    }
}

आप इस नमूना आवेदन की जांच कर सकते हैं ।


जर्सी 2.29.1 के साथ, मुझे jersey-hk2एक निर्भरता के रूप में जोड़ना पड़ा क्योंकि मुझे एक java.lang.IllegalStateException: InjectionManagerFactoryत्रुटि नहीं मिली थी ( यह प्रश्न देखें )। अन्यथा यह उदाहरण अच्छा काम करता है।
सारा एन

7

आपने शायद कुछ जावा कोड लिखे हैं जो आपके व्यावसायिक तर्क को लागू करते हैं और फिर आपने इसके लिए वेब सेवाओं के अंत बिंदु को उत्पन्न किया है।

एक महत्वपूर्ण बात यह है कि स्वतंत्र रूप से अपने व्यापार तर्क का परीक्षण करें। चूंकि यह शुद्ध जावा कोड है, आप इसे नियमित JUnit परीक्षणों के साथ कर सकते हैं।

अब, चूंकि वेब सेवाओं का हिस्सा सिर्फ एक अंतिम बिंदु है, जिसे आप सुनिश्चित करना चाहते हैं कि उत्पन्न पाइपलाइन (स्टब्स, आदि) आपके जावा कोड के साथ सिंक में हैं। आप ऐसा कर सकते हैं कि JUnit परीक्षण लिखकर, जो उत्पन्न वेब सेवा जावा क्लाइंट का आह्वान करता है। जब आप वेब सेवाओं के सामान को अपडेट किए बिना अपने जावा हस्ताक्षर बदलते हैं, तो यह आपको बताएगा।

यदि आपकी वेब सेवाओं की प्लंबिंग आपके बिल्ड सिस्टम द्वारा प्रत्येक बिल्ड पर स्वचालित रूप से उत्पन्न होती है, तो अंत बिंदुओं का परीक्षण करना आवश्यक नहीं हो सकता है (यह मानते हुए कि यह ठीक से उत्पन्न हुआ है)। व्यामोह के अपने स्तर पर निर्भर करता है।


2
आप काफी सही हैं, हालांकि मुझे वास्तविक HTTP प्रतिक्रियाओं का परीक्षण करने की भी आवश्यकता है, जो कि विशेष रूप से HTTP स्थिति कोड को लौटाते हैं।
Einar

6

हालांकि प्रश्न पोस्ट करने की तारीख से बहुत देर हो चुकी है, लेकिन यह सोचा कि यह उन लोगों के लिए उपयोगी हो सकता है जिनके पास एक समान प्रश्न है। जर्सी एक टेस्ट फ्रेमवर्क के साथ आता है जिसे जर्सी टेस्ट फ्रेमवर्क कहा जाता है जो आपको प्रतिक्रिया स्थिति कोड सहित अपनी रैस्टफुल वेब सेवा का परीक्षण करने की अनुमति देता है। आप इसका उपयोग ग्रिज़ली, HTTPServer और / या एंबेडेड ग्लासस्फ़िश जैसे हल्के कंटेनरों पर अपने परीक्षण चलाने के लिए कर सकते हैं। इसके अलावा, फ्रेमफ़ास्ट या टॉमकैट जैसे नियमित वेब कंटेनर पर आपके परीक्षणों को चलाने के लिए फ्रेमवर्क का उपयोग किया जा सकता है।


क्या आपके पास कॉल हैंडलर को मॉक करने के बारे में एक अच्छा उदाहरण है? जर्सीहॉट्पकॉल -> MyResource -> CallHandler.getSomething () हम यहां कॉलहैंडलर का मजाक कैसे उड़ा सकते हैं?
बालाजी बोगाराम रामनारायण

3

मैं Apache की HTTPClient (http://hc.apache.org/) का उपयोग रेस्टफुल सर्विसेज को कॉल करने के लिए करता हूं । एचटीटीपी क्लाइंट लाइब्रेरी आपको आसानी से प्राप्त करने, पोस्ट करने या अन्य किसी भी ऑपरेशन की आवश्यकता होती है। यदि आपकी सेवा xml बाइंडिंग के लिए JAXB का उपयोग करती है, तो आप HTTP अनुरोध से इनपुट और आउटपुट को क्रमबद्ध और अ-अयोग्य बनाने के लिए एक JAXBContext बना सकते हैं।


3

अल्केमी बाकी क्लाइंट जनरेटर पर एक नज़र डालें । यह दृश्य के पीछे जर्सी क्लाइंट का उपयोग करके आपके JAX-RS वेबसर्विस वर्ग के लिए एक प्रॉक्सी कार्यान्वयन उत्पन्न कर सकता है। प्रभावी रूप से आप अपने यूनिट परीक्षणों से सरल जावा विधियों के रूप में आपको वेबसर्विस विधियां कहेंगे। Http प्रमाणीकरण भी संभालता है।

कोई कोड पीढ़ी शामिल नहीं है अगर आपको बस परीक्षण चलाने की आवश्यकता है तो यह सुविधाजनक है।

अस्वीकरण: मैं इस पुस्तकालय का लेखक हूं।


2

इसे सरल रखें। Https://github.com/valid4j/http-matchers पर एक नज़र डालें जो मावेन सेंट्रल से आयात किया जा सकता है।

    <dependency>
        <groupId>org.valid4j</groupId>
        <artifactId>http-matchers</artifactId>
        <version>1.0</version>
    </dependency>

उपयोग उदाहरण:

// Statically import the library entry point:
import static org.valid4j.matchers.http.HttpResponseMatchers.*;

// Invoke your web service using plain JAX-RS. E.g:
Client client = ClientBuilder.newClient();
Response response = client.target("http://example.org/hello").request("text/plain").get();

// Verify the response
assertThat(response, hasStatus(Status.OK));
assertThat(response, hasHeader("Content-Encoding", equalTo("gzip")));
assertThat(response, hasEntity(equalTo("content")));
// etc...

1

एक महत्वपूर्ण बात यह है कि स्वतंत्र रूप से अपने व्यापार तर्क का परीक्षण करें

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

जर्सी और रैस्टैसी दोनों के पास क्लाइंट एप्लिकेशन हैं और RESTEasy के मामले में आप एक ही एनाउंसमेंट का उपयोग कर सकते हैं (यहां तक ​​कि एनोटेट इंटरफेस को भी कारक और आपके टेस्ट के क्लाइंट और सर्वर साइड पर उपयोग कर सकते हैं)।

REST नहीं कि यह सेवा आपके लिए क्या कर सकती है; REST इस सेवा के लिए आप क्या कर सकते हैं।


लोग कुछ क्रॉस कटिंग चिंताओं का परीक्षण करना चाह सकते हैं। उदाहरण के लिए सत्यापन, प्रमाणीकरण, वांछित HTTP हेडर आदि ताकि लोग अपने JAX-RS कोड का परीक्षण करना पसंद कर सकें।
फ्यरत के

मेरे आवेदन में, मैं "डीटीओ" कक्षाओं से "व्यावसायिक वस्तु" कक्षाओं के लिए "मैप" के लिए मॉडलमैपर का उपयोग करता हूं, जो अंतर्निहित "सेवा" वर्गों द्वारा समझा जाता है। यह उस चीज़ का एक उदाहरण है जो स्वतंत्र रूप से परीक्षण करने के लिए अच्छा होगा।
14

और कभी-कभी REST एप्लेट में इतनी कम जटिलता होती है कि मेरे वर्तमान मामले में मोक्स एप्लीकेशन लेयर से बड़ा होगा। :)
22

1

जैसा कि मैं समझता हूं कि इस मुद्दे के ऑटेर का मुख्य उद्देश्य व्यवसाय से जेएक्स आरएस परत को कम करना है। और यूनिट परीक्षण केवल पहले वाला है। दो बुनियादी समस्याओं का समाधान हमें यहाँ करना है:

  1. कुछ वेब / एप्लिकेशन सर्वर का परीक्षण करें, इसमें JAX RS घटक रखें। और केवल वे।
  2. JAX RS कंपोनेंट्स / REST लेयर के अंदर मॉक बिजनेस सेवाएं।

पहले वाले को Arquillian के साथ हल किया जाता है। दूसरे को पूरी तरह से आर्किक्लिकन और मॉक में वर्णित किया गया है

यहां कोड का एक उदाहरण है, यदि आप किसी अन्य एप्लिकेशन सर्वर का उपयोग करते हैं तो यह भिन्न हो सकता है, लेकिन मुझे आशा है कि आपको मूल विचार और फायदे मिलेंगे।

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.brandmaker.skinning.service.SomeBean;

/**
* Created by alexandr on 31.07.15.
*/
@Path("/entities")
public class RestBean
{
   @Inject
   SomeBean bean;

   @GET
   public String getEntiry()
   {
       return bean.methodToBeMoked();
   }
}

import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

import com.google.common.collect.Sets;

/**
*/
@ApplicationPath("res")
public class JAXRSConfiguration extends Application
{
   @Override
   public Set<Class<?>> getClasses()
   {
       return Sets.newHashSet(RestBean.class);
   }
}


public class SomeBean
{
   public String methodToBeMoked()
   {
       return "Original";
   }
}

import javax.enterprise.inject.Specializes;

import com.brandmaker.skinning.service.SomeBean;

/**
*/
@Specializes
public class SomeBeanMock extends SomeBean
{
   @Override
   public String methodToBeMoked()
   {
       return "Mocked";
   }
}

@RunWith(Arquillian.class)
public class RestBeanTest
{
   @Deployment
   public static WebArchive createDeployment() {
       WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
               .addClasses(JAXRSConfiguration.class, RestBean.class, SomeBean.class, SomeBeanMock.class)
               .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
       System.out.println(war.toString(true));
       return war;
   }

   @Test
   public void should_create_greeting() {
       Client client = ClientBuilder.newClient();
       WebTarget target = client.target("http://127.0.0.1:8181/test/res/entities");
       //Building the request i.e a GET request to the RESTful Webservice defined
       //by the URI in the WebTarget instance.
       Invocation invocation = target.request().buildGet();
       //Invoking the request to the RESTful API and capturing the Response.
       Response response = invocation.invoke();
       //As we know that this RESTful Webserivce returns the XML data which can be unmarshalled
       //into the instance of Books by using JAXB.
       Assert.assertEquals("Mocked", response.readEntity(String.class));
   }
}

नोटों की एक जोड़ी:

  1. Web.xml के बिना JAX RS कॉन्फ़िगरेशन का उपयोग यहां किया जाता है।
  2. JAX RS क्लाइंट का उपयोग यहां किया गया है (कोई RESTEasy / जर्सी नहीं, वे अधिक सुविधाजनक API का खुलासा करते हैं)
  3. जब परीक्षण शुरू होता है, तो अर्क्विलियन का धावक काम करना शुरू कर देता है। यहाँ आप पा सकते हैं कि आवश्यक एप्लिकेशन सर्वर के साथ Arquillian के लिए परीक्षणों को कैसे कॉन्फ़िगर किया जाए।
  4. चुने हुए एप्लिकेशन सर्वर के आधार पर, परीक्षण में एक यूआरएल थोड़ा अलग होगा। एक अन्य पोर्ट का उपयोग किया जा सकता है। मेरे उदाहरण में ग्लासफिश एंबेडेड द्वारा 8181 का उपयोग किया जाता है।

आशा है, यह मदद करेगा।


क्या जर्सी टेस्ट ढांचे में निर्मित इस प्रकार का समर्थन है? मैं अपने प्रोजेक्ट में "अभी तक एक और फ्रेमवर्क" और इसके सभी जार जोड़ने में संकोच कर रहा हूं अगर मेरे पास पहले से ही जर्सी के साथ कुछ उपलब्ध है।
जकरक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.