Testing a JAX-RS Web Service?

前端 未结 10 1235
[愿得一人]
[愿得一人] 2020-12-04 08:36

I\'m currently looking for ways to create automated tests for a JAX-RS (Java API for RESTful Web Services) based web service.

I basically need a way to send it cert

10条回答
  •  自闭症患者
    2020-12-04 09:33

    As I understand the main purpose of the auther of this issue is to decouple JAX RS layer from business one. And unit test only the first one. Two basic problems here we have to resolve:

    1. Run in test some web/application server, put JAX RS components in it. And only them.
    2. Mock business services inside JAX RS components/REST layer.

    The first one is solved with Arquillian. The second one is perfectly described in arquillican and mock

    Here is an example of the code, it may differ if you use another application server, but I hope you'll get the basic idea and advantages.

    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> 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));
       }
    }
    

    A couple of notes:

    1. JAX RS configuration without web.xml is used here.
    2. JAX RS Client is used here (no RESTEasy/Jersey, they expose more convenient API)
    3. When test starts, Arquillian's runner starts working. Here you can find how to configure tests for Arquillian with needed application server.
    4. Depending on the chosen application server, an url in the test will differ a little bit. Another port may be used. 8181 is used by Glassfish Embedded in my example.

    Hope, it'll help.

提交回复
热议问题