Resource testing with Guice Injection help

680 views
Skip to first unread message

Felix Gao

unread,
Feb 11, 2014, 12:16:57 AM2/11/14
to dropwiz...@googlegroups.com
hello, I am running DropWizard 0.6.2 and having the following problem when I am testing my resources.

@Path("/api/browse")
public class BrowseServiceResource {
    private static final Logger LOGGER = LoggerFactory.getLogger(BrowseServiceResource.class);
    private final ApiService apiService;

    @Inject
    public BrowseServiceResource(ApiService apiService){
        this.apiService = apiService;
    }

    @Metered
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/{id}")
    public Response getBrowseData(@PathParam("id") final int ordinal,
                                  @QueryParam("tags") final List<String> tags,
                                  @QueryParam("radius") @DefaultValue("2000.0") final double radius) throws IOException {
        Browse.Categories category = Browse.Categories.fromOrdinal(ordinal);
        javax.ws.rs.core.Response.ResponseBuilder rb  =  javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.OK);
        final JsonNode node = apiService.search(null, null, 40000, 2, 0, 40);
        rb.entity(node.toString());
        return rb.build();
    }
}


public class BrowseServiceResourceTest extends ResourceTest {
    private ApiService apiService = mock(ApiService.class);
    //node is some predefined JsonNode object that is super large

    @Override
    protected void setUpResources() throws Exception {
        Injector injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                binder().bind(ApiService.class).toInstance(apiService);
            }
        });
        final BrowseServiceResource resource = injector.getInstance(BrowseServiceResource.class);
        doReturn(node).when(apiService).search(anyString(), anyList(), anyInt(), anyInt(),  anyInt(), anyInt());
        addResource(resource);
    }

@Test
    public void simpleResourceTest() throws Exception {
        BrowseServiceResource resource = client().resource("/api/browse/1").get(BrowseServiceResource.class);
        Response response = resource.getBrowseData(1, 0.0, 0.0, new ArrayList<String>(), 0.0);
        System.out.println(response.getEntity());
    }
}

the BrowseServiceResource object returned by the get call is throwing the exception 
com.sun.jersey.api.client.ClientHandlerException: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.katami.resources.BrowseServiceResource]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: java.io.ByteArrayInputStream@5dd183b7; line: 1, column: 2]
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:575)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:517)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:684)
at com.sun.jersey.api.client.WebResource.get(WebResource.java:191)
at com.katami.resources.BrowseServiceResourceTest.simpleResourceTest(BrowseServiceResourceTest.java:93)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.katami.resources.BrowseServiceResource]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: java.io.ByteArrayInputStream@5dd183b7; line: 1, column: 2]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:400)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:289)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1169)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:625)
at com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:448)
at com.yammer.dropwizard.jersey.JacksonMessageBodyProvider.readFrom(JacksonMessageBodyProvider.java:61)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:565)
... 32 more

I think the problem is because it find the right constructor to call when instantiating a new instance of BrowseServiceResource.  What can I do to solve this problem?

thanks,

Felix

   

Nick Telford

unread,
Feb 11, 2014, 3:42:56 AM2/11/14
to dropwiz...@googlegroups.com
In your test, change ".get(BrowseServiceResource.class);" to "get(Response.class);"

Felix Gao

unread,
Feb 13, 2014, 10:58:29 PM2/13/14
to dropwiz...@googlegroups.com
Thanks Nick for the suggestion, I not have a different error, but I tried to google the error but my googlefu is very weak. Didn't find any useful result.  Any ideas? 
 
com.sun.jersey.api.client.ClientHandlerException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of javax.ws.rs.core.Response, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: java.io.ByteArrayInputStream@6302ae84; line: 1, column: 1]
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:575)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:517)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:684)
at com.sun.jersey.api.client.WebResource.get(WebResource.java:191)
at com.katami.resources.BrowseServiceResourceTest.simpleResourceTest(BrowseServiceResourceTest.java:90)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of javax.ws.rs.core.Response, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: java.io.ByteArrayInputStream@6302ae84; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:624)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:115)

Felix Gao

unread,
Feb 19, 2014, 9:15:35 PM2/19/14
to dropwiz...@googlegroups.com
I changed the line 
        Response resource = client().resource("/api/browse/1").get(Response.class);
to 
        Response resource = client().resource("/api/browse/1").get(ResponseImpl.class);

now I have 
com.sun.jersey.api.client.ClientHandlerException: com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.Object]]]
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:575)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:517)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:684)
at com.sun.jersey.api.client.WebResource.get(WebResource.java:191)
at com.katami.resources.BrowseServiceResourceTest.simpleResourceTest(BrowseServiceResourceTest.java:91)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.Object]]]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:269)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:325)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:633)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:427)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:295)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:342)
at com.fasterxml.jackson.databind.ObjectReader._findRootDeserializer(ObjectReader.java:1316)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1164)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:625)
at com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:448)
at com.yammer.dropwizard.jersey.JacksonMessageBodyProvider.readFrom(JacksonMessageBodyProvider.java:61)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:565)
... 32 more
Caused by: java.lang.IllegalArgumentException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.Object]]]
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createMapDeserializer(BasicDeserializerFactory.java:926)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:361)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 47 more

anyone knows how to solve this?
Reply all
Reply to author
Forward
0 new messages