How to test a REST client Jersey ?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How to test a REST client Jersey ?

Anthony Dahanne
Hello Reno !
and thank you for your answer !
Unfortunately, I haven't found out how to use the Jersey test framework to test my client side REST consumer.

so, to be more precise, I want to to check that this method :


public Item getItem(int itemId) throws ItemGalleryException {

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(galleryUrl);
stringBuilder.append(itemId);
WebResource r = client.resource(stringBuilder.toString());

Item response = r.accept(
MediaType.APPLICATION_JSON_TYPE).
get(Item.class);
return response;
}

when called, sends this request :

GET myUrl/itemId HTTP/1.1
Host: example.com
Content-Length: 0

To do this, I began writing this test :



@Test
public void getItemTest() throws ItemGalleryException{

LowLevelAppDescriptor descriptor = new LowLevelAppDescriptor.Builder("net.dahanne.g3restapi.business").build();
InMemoryTestContainerFactory containerFactory = new InMemoryTestContainerFactory();
TestContainer create = containerFactory.create(URI.create("http://example.com/myUrl/"), descriptor);
Client client = create.getClient();

ItemRestImpl itemRest = new ItemRestImpl("http://example.com/myUrl/");
itemRest.setClient(client);
Item item = itemRest.getItem(2);
assertEquals(2, item.entity.id);

}

But it generates this exception :

java.lang.NullPointerException
at com.sun.jersey.spi.container.ContainerResponse.mapException(ContainerResponse.java:419)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:998)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
at com.sun.jersey.test.framework.impl.container.inmemory.TestResourceClientHandler.handle(TestResourceClientHandler.java:116)
at com.sun.jersey.api.client.Client.handle(Client.java:551)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:556)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:69)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:451)
at net.dahanne.g3restapi.business.ItemRestImpl.getItem(ItemRestImpl.java:38)
at net.dahanne.g3restapi.business.ItemRestImplTest.getItemTest(ItemRestImplTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


All i want to do is to have an object providing me with the HTTP request generated by Jersey !
I'm not sure anyway that this article :

http://blogs.sun.com/naresh/entry/jersey_test_framework_re_visited
 describes this in any way, it seems to be oriented on the testing of a server side REST api.

I want to test my client...

Thanks for your help !
Anthony



Date: Tue, 15 Jun 2010 17:44:03 +0200
From: [hidden email] <[hidden email]>
Content-Type: text/plain; charset=ISO-8859-1
Subject: [Jersey] How to test a REST client Jersey ?

hello anthony,

the jersey 1.2 version is great for testing
check out this :
http://blogs.sun.com/naresh/entry/jersey_test_framework_re_visited
we're using it everyday and it great (thanks to the jersey team)

Hope this help

S.


> Hello !
> I'm using Jersey to consume a REST service in JSON.
> I've able to successfully consume the service (using only gor now) . but
> now, as I'm starting to unit test this getService(int resourceId) method, I
> realize that I don't know how to write this test !
> What I would like is to check that my request is correct, meaning, conform
> to what the REST service is expecting.
> So , for example, my unit test would :
> *create an instance of my implentation class
> *call the getService(int resourceId)
> *compare the generated request to what I expected to be sent
>
> I've seen that a Test framework exists for Jersey server side (JesrseyTest)
>
> Is there something similar for the client side, so that I can unit test my
> client side API without consuming the real service ?
>
> Thank you for your answers !
> Anthony
>





Reply | Threaded
Open this post in threaded view
|

Re: How to test a REST client Jersey ?

Frédéric Bouquet
Hi Anthony,

I understand your problem and I don't think something is already in
the test framework to automate what you need. I think you may create
some kind of "virtual server" with grizzly for example and check at a
lower level (with JUnit not Jersey test framework) what is sent by
your client.

I think you could create and lauch a grizzly server (or in memory but
I have not used it yet) in your setup methods. Then is your test
cases, you call your client methods to get some informations, but a
maybe best way should be to use "test made" filters to your grizzly
test server to intercept sent and received request from server view.
But, I don't realy know if the jerser-server's packages are "linked"
to the jersey test framework (to use resources) so you may need to
write your test server in your code and call it from the test cases.

Hope my "ramblings" could help :)

--
Frédéric Bouquet
http://www.espacedefouille.org/

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: How to test a REST client Jersey ?

Paul Sandoz
Administrator
In reply to this post by Anthony Dahanne
Hi Anthony,

We don't having anything that focuses on the client specifically. One  
thing you could do is write your own client handler implementation  
that allows you to implement the checking of the ClientRequest and the  
returning of a ClientResponse.

You can do this as follows:

   Client.create(new ClientHandler() {
          public ClientResponse handle(ClientRequest cr) throws  
ClientHandlerException {
            ...
          }
     });


The other way to do this is to turn the problem around and use a  
"dummy" resource, it is almost what you have done using the  
InMemoryTestContainerFactory but you are forgetting to do the  
create.start() and create.stop().

public class InMemoryClassesTest extends JerseyTest {

     @Override
     protected TestContainerFactory getTestContainerFactory() {
         return new InMemoryTestContainerFactory();
     }

     @Path("root")
     public static class TestResource {
         @GET
         public ... get(@Context HttpContext hc) {
             // From hc you can get the HttpRequestContext
             // make assertions here
         }

     }

     public InMemoryClassesTest() {
         super(new LowLevelAppDescriptor.Builder(TestResource.class).
                 contextPath("context").
                 build());
     }

     @Test
     public void testGet() {
         WebResource r = resource().path("root");

         String s = r.get(String.class);
     }
}

However, this does not give you direct access to the ClientRequest and  
instead gives you access to the server-side HttpRequestContext which  
is directly derived from ClientRequest in the case of the in-memory  
support.

Paul.

On Jun 16, 2010, at 2:57 AM, Anthony Dahanne wrote:

> Hello Reno !
> and thank you for your answer !
> Unfortunately, I haven't found out how to use the Jersey test  
> framework to test my client side REST consumer.
>
> so, to be more precise, I want to to check that this method :
>
>
>
> public Item getItem(int itemId) throws ItemGalleryException {
>
> StringBuilder stringBuilder = new StringBuilder();
> stringBuilder.append(galleryUrl);
> stringBuilder.append(itemId);
> WebResource r = client.resource(stringBuilder.toString());
>
>
>   Item response = r.accept(
>        MediaType.APPLICATION_JSON_TYPE).
>        get(Item.class);
>   return response;
> }
>
> when called, sends this request :
>
>  GET myUrl/itemId HTTP/1.1
>
>  Host: example.com
>  Content-Length: 0
>
> To do this, I began writing this test :
>
>
>
> @Test
> public void getItemTest() throws ItemGalleryException{
>
> LowLevelAppDescriptor descriptor =  new  
> LowLevelAppDescriptor
> .Builder("net.dahanne.g3restapi.business").build();
>
> InMemoryTestContainerFactory containerFactory =  new  
> InMemoryTestContainerFactory();
> TestContainer create = containerFactory.create(URI.create("http://example.com/myUrl/ 
> "), descriptor);
>
> Client client = create.getClient();
>
> ItemRestImpl itemRest = new ItemRestImpl("http://example.com/ 
> myUrl/");
> itemRest.setClient(client);
> Item item = itemRest.getItem(2);
>
> assertEquals(2, item.entity.id);
>
> }
>
> But it generates this exception :
>
> java.lang.NullPointerException
> at  
> com
> .sun
> .jersey
> .spi.container.ContainerResponse.mapException(ContainerResponse.java:
> 419)
>
> at  
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:998)
> at  
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
> at  
> com
> .sun
> .jersey
> .test
> .framework
> .impl
> .container
> .inmemory
> .TestResourceClientHandler.handle(TestResourceClientHandler.java:116)
>
> at com.sun.jersey.api.client.Client.handle(Client.java:551)
> at com.sun.jersey.api.client.WebResource.handle(WebResource.java:556)
> at com.sun.jersey.api.client.WebResource.access
> $200(WebResource.java:69)
> at com.sun.jersey.api.client.WebResource
> $Builder.get(WebResource.java:451)
>
> at  
> net
> .dahanne.g3restapi.business.ItemRestImpl.getItem(ItemRestImpl.java:38)
> at  
> net
> .dahanne
> .g3restapi
> .business.ItemRestImplTest.getItemTest(ItemRestImplTest.java:33)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>
> at  
> sun
> .reflect
> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at  
> sun
> .reflect
> .DelegatingMethodAccessorImpl
> .invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
>
> at org.junit.runners.model.FrameworkMethod
> $1.runReflectiveCall(FrameworkMethod.java:44)
> at  
> org
> .junit
> .internal
> .runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
> at  
> org
> .junit
> .runners
> .model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
>
> at  
> org
> .junit
> .internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:
> 20)
> at  
> org
> .junit
> .internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
> at  
> org
> .junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:
> 31)
>
> at  
> org
> .junit
> .runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
> 73)
> at  
> org
> .junit
> .runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
> 46)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
>
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
> at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
> at  
> org
> .junit
> .internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
>
> at  
> org
> .junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:
> 31)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
> at  
> org
> .eclipse
> .jdt
> .internal
> .junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
>
> at  
> org
> .eclipse
> .jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at  
> org
> .eclipse
> .jdt
> .internal
> .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at  
> org
> .eclipse
> .jdt
> .internal
> .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>
> at  
> org
> .eclipse
> .jdt
> .internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at  
> org
> .eclipse
> .jdt
> .internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:
> 197)
>
>
> All i want to do is to have an object providing me with the HTTP  
> request generated by Jersey !
>
> I'm not sure anyway that this article :
>
> http://blogs.sun.com/naresh/entry/jersey_test_framework_re_visited
>  describes this in any way, it seems to be oriented on the testing  
> of a server side REST api.
>
>
> I want to test my client...
>
> Thanks for your help !
> Anthony
>
>
>
> Date: Tue, 15 Jun 2010 17:44:03 +0200
> From: [hidden email] <[hidden email]>
>
> Content-Type: text/plain; charset=ISO-8859-1
> Subject: [Jersey] How to test a REST client Jersey ?
>
> hello anthony,
>
> the jersey 1.2 version is great for testing
> check out this :
> http://blogs.sun.com/naresh/entry/jersey_test_framework_re_visited
>
> we're using it everyday and it great (thanks to the jersey team)
>
> Hope this help
>
> S.
>
>
> > Hello !
> > I'm using Jersey to consume a REST service in JSON.
> > I've able to successfully consume the service (using only gor  
> now) . but
>
> > now, as I'm starting to unit test this getService(int resourceId)  
> method, I
> > realize that I don't know how to write this test !
> > What I would like is to check that my request is correct, meaning,  
> conform
>
> > to what the REST service is expecting.
> > So , for example, my unit test would :
> > *create an instance of my implentation class
> > *call the getService(int resourceId)
> > *compare the generated request to what I expected to be sent
>
> >
> > I've seen that a Test framework exists for Jersey server side  
> (JesrseyTest)
> >
> > Is there something similar for the client side, so that I can unit  
> test my
> > client side API without consuming the real service ?
>
> >
> > Thank you for your answers !
> > Anthony
> >
>
>
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]