3

I have a REST api that returns an object in json format, with Content-Type of application/json, pretty standard.

I'm creating a basic TestNg Jersey test using Jersey's test framework, and want to run a simple test against an external container deployed independently in Tomcat.

The setup seems OK for tests that don't need to read the entity of a response, but those that do fail with:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class com.test.Status, genericType=class com.specktro.orchid.rest.api.Status.
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:225)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:149)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:399)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)
    at com.specktro.orchid.rest.api.tests.CoreTest.test(CoreTest.java:81)
    at com.specktro.orchid.rest.api.tests.CoreTest.second(CoreTest.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

I'm configuring the test like so:

public class CoreTest extends ContainerPerClassTest {

    @Override
    public TestContainerFactory getTestContainerFactory() {
        return new ExternalTestContainerFactory();
    }

    @Override
    protected Application configure() {
        return new ResourceConfig();
    }

    @Test
    private void test() {
        final Response response = target("/status").request()
                .accept(MediaType.APPLICATION_JSON).get();

        Assert.assertEquals(response.getStatus(), 200);

        // FAILS HERE
        Status status = response.readEntity(Status.class);
    }

    ...

}

At the indicated line it fails with response.readEntity(Status.class);.

This is a Maven project, and these are the relevant dependencies:

  <dependencies>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.4.1.1</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-json-provider</artifactId>
      <version>2.4.1</version>
    </dependency>

    <dependency>
      <groupId>org.glassfish.jersey.containers</groupId>
      <artifactId>jersey-container-servlet</artifactId>
      <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
      <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-common</artifactId>
      <version>2.9.1</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.test-framework</groupId>
        <artifactId>jersey-test-framework-core</artifactId>
        <version>2.10.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
        <artifactId>jersey-test-framework-provider-bundle</artifactId>
        <version>2.10.1</version>
        <type>pom</type>
        <scope>test</scope>
    </dependency>
    <dependency> 
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.8.8</version>
        <scope>test</scope>
    </dependency>

  </dependencies>

The com.test.Status class I'm trying to read has an empty constructor as required by JAX-RS.

Anyone knows why the test would fail like this? As you can see I'm using Jersey 2.x.

Any help is greatly appreciated!

Thanks!

Edy Bourne
  • 5,679
  • 13
  • 53
  • 101
  • For our FTA tests we get the entity as a string and then use a JSON parser to marshal into the object. – David W Jul 22 '14 at 23:43

2 Answers2

6

I found the issue.. I was actually missing this dependency:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey.version}</version>
</dependency>

Now it works fine.

Thanks anyways everyone!

Edy Bourne
  • 5,679
  • 13
  • 53
  • 101
  • This introduces version conflicts for me. The `jersey-media-json-jackson` artifact is out of date with the rest of jackson (it's using 2.3.2.) – 2rs2ts Oct 14 '14 at 18:33
1

Have you checked if the REST API is returning the json string correctly? May be using a curl command?

If not, please check the server configuration. You need to enable POJOMappingFeature in web.xml.

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>
user1401472
  • 2,203
  • 3
  • 23
  • 37