1. Overview
In this tutorial, we'll look at the built-in JUnit test rules. In the end, we'll have the knowledge to use them at appropriate places.
2. Get Current Test Name
Let's start with the TestName rule.
The TestName rule enables us to get the current test name:
public class TestNameRuleTest {
@Rule
public TestName testName = new TestName();
@Test
public void shouldGetTestName() {
assertThat(testName.getMethodName()).isEqualTo("shouldGetTestName");
}
}
Here we're getting the test method's name, shouldGetTestName.
3. Collect Errors in Unit Test
ErrorCollector lets us collect errors and evaluate at the end of the unit test:
public class ErrorCollectorRuleTest {
@Rule
public final ErrorCollector collector = new ErrorCollector();
@Test
public void shouldCollectErrors() {
Service service = new Service();
if (!service.canRead()) {
collector.addError(new Throwable("Cannot read!"));
}
if (!service.canWrite()) {
collector.addError(new Throwable("Cannot write!"));
}
}
public static class Service {
public boolean canRead() {
return false;
}
public boolean canWrite() {
return false;
}
}
}
Notice that, the test isn't failing at the first error, but continuing to execute. In the end, all failures will be printed.
4. Set Timeout in Unit Test
Timeout class lets us set a timeout for all tests in a test class:
public class TimeoutRuleTest {
@Rule
public Timeout timeout = new Timeout(1000, TimeUnit.MILLISECONDS);
@Test
public void shouldNotTimeout() {
sleep(500);
}
@Test
public void shouldTimeout() {
sleep(1500);
}
private void sleep(long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
fail();
}
}
}
Here, we're defining the timeout to be 1000 milliseconds. If the timeout is reached, it'll throw an exception.
5. Define Expectations on Exceptions
Next, ExpectedException lets us define exceptions that we expect to be thrown:
public class ExpectedExceptionRuleTest {
@Rule
public final ExpectedException thrown = ExpectedException.none();
@Test
public void shouldThrowException() {
thrown.expect(NullPointerException.class);
thrown.expectMessage("Value is null");
throw new NullPointerException("Value is null");
}
}
Note that we can define expectations on both the exception type and message.
6. Create Temporary Files and Folders in Unit Test
TemporaryFolder helps us when creating temporary files and folders in our tests:
public class TemporaryFolderRuleTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void shouldCreateNewFile() throws IOException {
File file = temporaryFolder.newFile();
assertThat(file.isFile()).isTrue();
assertThat(file.isDirectory()).isFalse();
}
@Test
public void shouldCreateNewFileWithGivenName() throws IOException {
String fileName = "test.txt";
File file = temporaryFolder.newFile(fileName);
assertThat(file.getName()).isEqualTo(fileName);
assertThat(file.isFile()).isTrue();
assertThat(file.isDirectory()).isFalse();
}
@Test
public void shouldCreateNewFolder() throws IOException {
File folder = temporaryFolder.newFolder();
assertThat(folder.isFile()).isFalse();
assertThat(folder.isDirectory()).isTrue();
}
@Test
public void shouldCreateNewFolderWithGivenName() throws IOException {
String folderName = "test";
File folder = temporaryFolder.newFolder(folderName);
assertThat(folder.getName()).isEqualTo(folderName);
assertThat(folder.isFile()).isFalse();
assertThat(folder.isDirectory()).isTrue();
}
}
Here, we're creating temporary files and folders. Note that we can specify the file/folder name. Moreover, these files will be removed when the test is completed.
7. Manage External Resources
Lastly, ExternalResource provides a template to set up and clean up resources.
It has two methods we should implement: before() and after():
public class ExternalResourceRuleTest {
private Server myServer = new Server();
@Rule
public final ExternalResource resource = new ExternalResource() {
@Override
protected void before() throws Throwable {
myServer.connect();
}
@Override
protected void after() {
myServer.disconnect();
}
};
@Test
public void shouldManageExternalResource() {
System.out.println("Client can connect now!");
}
public static class Server {
public void connect() {
System.out.println("Connecting to the server");
}
public void disconnect() {
System.out.println("Disconnecting from the server");
}
}
}
We're connecting to a server in the before() method. Then we're disconnecting from the server in after() method.
8. Summary
In this tutorial, we've seen different test rules which JUnit provides by default.
As always, the source code is available on Github.