2016. május 11., szerda

How to use @Rule annotation instead of the expected keyword to unit test exceptions


The usual way for unit testing expected exceptions looks like this:


@Test(expected = ConfigurationException.class)

It has although the following disadvantages:


  • you can not check details of the exception, like message or cause
  • you can not do anything with the exception

It is a better solution to use the @Rule annotation from JUnit.


import org.hamcrest.core.StringContains;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void crowdUserDataThrowsExceptionForBlankInput() {
    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("Username from CROWD must not be empty.");
    new CrowdDataImporter().new CrowdUserIdHolder("    ");
}

It is also possible to check the expected exception message, using some subclass of Matcher:

@Test
public void testCreateSchedulerCalendar_emptyParam() {
exception.expect(SchedulerException.class);
exception.expectMessage(new StringContains("job.scheduler.fixtime"));
avatarSyncJobScheduler.createSchedulerCalendar("");
}

You can find other Matcher implementations in the package org.hamcrest.core. It is per default added to the JUnit, so there is no need to add other maven dependencies is needed.