javarestjerseyjax-rsexceptionmapper

Jersey test - ExceptionMapper - UniformInterfaceException when HTTP status is not 200


I have to test Jersey 1.19 with jersey-test-framework-grizzly2. There is configuration class with registered REST endpoint and exception mapper class:

public class ConfiguredMyServiceTest extends JerseyTest {

    @Override
    protected int getPort(int defaultPort) {
        return 8080;
    }

    public static class AppConfig extends DefaultResourceConfig {   
        public AppConfig() {
            getSingletons().add(new ExceptionMapperProvider());
            getSingletons().add(new MyService());
        }
    }

    @Override
    public WebAppDescriptor configure() {
        return new WebAppDescriptor.Builder()
            .initParam(WebComponent.RESOURCE_CONFIG_CLASS, 
                AppConfig.class.getName())
                .build();
    }
}

When I execute/test REST endpoint which returns HTTP status 200 it works well.

If exception is thrown, exception mapper handles it well and forms return object javax.ws.rs.core.Response with error code:

@Provider
@Singleton
public class ExceptionMapperProvider implements ExceptionMapper<Exception>{

    @Override
    public Response toResponse(final Exception exception){
        return Response.status(HttpStatusCodes.STATUS_CODE_SERVER_ERROR).entity(new BasicResponse(InternalStatus.UNHANDLED_EXCEPTION, exception.getMessage())).type(MediaType.APPLICATION_JSON).build();
    }
}

However, I get

com.sun.jersey.api.client.UniformInterfaceException: POST http://localhost:8080/v1/my-service/ returned a response status of 401 Unauthorized

when I try to assert Response in my JUnit tests. How to get well formed response instead of UniformInterfaceException?


Solution

  • Changed expected class type to com.sun.jersey.api.client.ClientResponse

    protected ClientResponse executeGet(String path){
        WebResource resource = resource().path(path);
        Builder builder = resource.header("Content-Type", "application/json;charset=UTF-8");
        return builder.get(ClientResponse.class);
    }
    

    Now it is able to handle various HTTP statuses and parse underlying response:

    ClientResponse clientResponse = executeGet("/info");
    
    if (clientResponse.getStatus() == 200)
        CustomResponseType customResponse = clientResponse.getEntity(CustomResponseType.class);