expect exception in junit tests

831 views
Skip to first unread message

Adam Parrish

unread,
Aug 22, 2012, 6:53:55 PM8/22/12
to dropwiz...@googlegroups.com
I have a unit test I'd like to make sure checks for an exception that should come from a Resource class. The resource method is:

public User add(User user) throws UserResourceException {
        try {
            if (!EmailValidator.getInstance().isValid(user.getEmail()))
                throw new WebApplicationException(new UserResourceException(UserResourceException.INVALID_EMAIL));
            else if (userDao.getUserCount(user.getEmail()) >= 1) {
                throw new WebApplicationException(new UserResourceException(UserResourceException.IN_USE_EMAIL));
            } else {
                Long userId = userDao.insert(user.getFirstName(),
                        user.getEmail(),
                        null,
                        user.getApiKey(),
                        new Date(),
                        new Date()
                );
                user = userDao.getUser(userId);
            }
        } catch (DBIException dbException) {
            LOG.error("DB EXCEPTION", dbException);
            throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
        }

        user.hidePassword();

        return user;
    }

The above code should throw a WebApplicationException when the user already exists or if a bad email is passed in. Here is an example unit test I would hope should work:

    @Test(expected = WebApplicationException.class)
    public void testAddNonUniqueEmail() {
        insertTestData();
        User user = new User("Different Name", "some...@gmail.com", new Password("pw555666"));
        client().resource(new MemmeeURLBuilder().setBaseURL(UserResource.BASE_URL).setMethodURL("user").build()).post(user);
    }

However I get the following exception instead of the expected one:

java.lang.Exception: Unexpected exception, expected<javax.ws.rs.WebApplicationException> but was<com.sun.jersey.api.client.UniformInterfaceException>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:31)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
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.sun.jersey.api.client.UniformInterfaceException: Client response status: 500
at com.sun.jersey.api.client.WebResource.voidHandle(WebResource.java:707)
at com.sun.jersey.api.client.WebResource.post(WebResource.java:236)
at com.something.UserResourceTest.testAddNonUniqueEmail(UserResourceTest.java:112)
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:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:22)
... 21 more

Is there a documented correct way to do this? Also is there a more appropriate way to bubble up the exceptions to the client using this API?

Christopher Elkins

unread,
Aug 22, 2012, 7:50:01 PM8/22/12
to dropwiz...@googlegroups.com
On Aug 22, 2012, at 3:53 PM, Adam Parrish wrote:

> The above code should throw a WebApplicationException when the user already exists or if a bad email is passed in. Here is an example unit test I would hope should work:
>
> @Test(expected = WebApplicationException.class)
> public void testAddNonUniqueEmail() {
> insertTestData();
> User user = new User("Different Name", "some...@gmail.com", new Password("pw555666"));
> client().resource(new MemmeeURLBuilder().setBaseURL(UserResource.BASE_URL).setMethodURL("user").build()).post(user);
> }
...
> However I get the following exception instead of the expected one:

Your expectation is incorrect. JAX-RS 1.x does not define a client API, so there's no guarantee that you'll receive a WebApplicationException. As you've discovered the Jersey client raises an exception of its own type.

> Is there a documented correct way to do this? Also is there a more appropriate way to bubble up the exceptions to the client using this API?

If you are not interested in the HTTP response code, then just replace WebApplicationException with UniformInterfaceException as your expected exception.

However, if you are interested (e.g., testing entity validation), then you need to capture the client response. For example,

ClientResponse response = client().resource(new MemmeeURLBuilder().setBaseURL(UserResource.BASE_URL).setMethodURL("user").build()).post(ClientResponse.class, user);
assertEquals(ClientResponse.Status.BAD_REQUEST, response.getClientResponseStatus());

--
Christopher Elkins

Reply all
Reply to author
Forward
0 new messages