dushkin
dushkin

Reputation: 2111

Spring: Fail to catch the thrown exception

I have the following negative test code (needs to fail and throw an exception):

@Test
public void testInventoryControllerGetNonExistingRegion() {

    final String name = "ME_2";
    RegionConfiguration refRegionConfiguration = prepareReferenceObject(name);

    try(
        inventoryRegionController.get(null,name);
    } catch (EntityDoesNotExistException e){

        //report something...
    }
}

The test calls the following method get() and SHOULD throw an EntityDoesNotExistException object.

@ApiOperation(value = "Get a region")
@RequestMapping(value = "regions/{" + REGION + "}", method = RequestMethod.GET)
public RegionConfiguration get(@RequestHeader(value = AUTHORIZATION_HEADER, defaultValue = "Bearer {{JWT}}") String authorization,
                               @PathVariable(REGION) String regionName) throws EntityDoesNotExistException {

    InventoryRegionEntity inventoryRegionEntity = null;
    inventoryRegionEntity = RegionInventoryService.find(regionName);

    if(null != inventoryRegionEntity)
        return RegionConfigurationMapper.mapInventoryRegionEntity(inventoryRegionEntity);
    else
        throw new EntityDoesNotExistException(InventoryRegionEntity.class, regionName);
}

The get() method DOES THROW the exception as required (I had a breakpoint and verified)! But my test never catches it. And that is becuase what I get is an

HttpServerErrorException: 500 null

And this exception is really being caught by the catch clause. Why is that happening here?

Thanks!

Upvotes: 0

Views: 254

Answers (4)

dushkin
dushkin

Reputation: 2111

The solution that worked for me is as follows:

try{

   //something...

}catch(HttpClientErrorException | HttpServerErrorException e) {

            ObjectMapper objectMapper = new ObjectMapper();
            Context context = null;
            try {
                context = objectMapper.readValue(e.getResponseBodyAsString(), Context.class);
            } catch (IOException ioExc) {
                ioExc.printStackTrace();
            }
            assertEquals("Failed on ", context.getType(), ExceptionFromServer.class.getTypeName());
        }

Upvotes: 0

cralfaro
cralfaro

Reputation: 5948

To verify the exception you could use this code, I think is cleaner and avoid to use try/catch inside your test

@Test(expected = HttpServerErrorException.class) 
public void testInventoryControllerGetNonExistingRegion() {
    final String name = "ME_2";
    RegionConfiguration refRegionConfiguration = prepareReferenceObject(name);
    inventoryRegionController.get(null,name);
}

Upvotes: 0

Sergey Prokofiev
Sergey Prokofiev

Reputation: 1885

The thing is that Spring does some durty work for you. In this particular case your exception will be enveloped to HTTP error, because REST is just an approach. Since you don't have any configuration about exception mapping, server will translate it to HTTP 500 - Server error. I think the best way for you to do the test is

@Test
public void testInventoryControllerGetNonExistingRegion() {
    final String name = "ME_2";
    RegionConfiguration refRegionConfiguration = prepareReferenceObject(name);

    try(
        inventoryRegionController.get(null,name);
        Assert.fail(); // don't forget to fail your test in no exception thrown
    } catch (HttpServerErrorException e){
        Assert.notNull(e);
        Assert.assertTrue(e.getCause() instanceof EntityDoesNotExistException);
    }
}

Hope it helps!

Upvotes: 2

Yoav Gur
Yoav Gur

Reputation: 1396

EntityDoesNotExistException is the exception on the server side.
When you call your code via REST, the exception on the server side is translated to a JSON string, returned to the client side as an HTTP response with that JSON string in the body, and then converted back to a (different) exception on the client side, depending on the REST framework you are using. (In your case: HttpServerErrorException).

Upvotes: 1

Related Questions