JUnit
Learn about JUnit and its features.
We'll cover the following
What is JUnit?
JUnit is a simple framework to write repeatable tests.
A typical JUnit 4.x test consists of multiple methods annotated with the @Test
annotation.
At the top of every JUnit test class, we should include all the static Assert methods and annotations like so:
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.Before;
import org.junit.After;
Use the @Before
to annotate initialization methods that are run before every test and @After
to
annotate break-down methods that are run after every test.
Each test method should test one thing, and the method name should reflect the test’s purpose. For example:
public void toStringYieldsTheStringRepresentation() {
String[] array = {"a", "b", "c"};
ArrayWrapper<String> arrayWrapper = new ArrayWrapper<String>(array);
assertEquals("[a, b, c]", arrayWrapper.toString());
}
Hamcrest
In more recent versions (JUnit 4.4+), JUnit also includes Hamcrest matchers:
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
Then you can create more readable tests using the Hamcrest core-matchers. For example:
@Test
public void sizeIs10() {
assertThat(wrapper.size(), is(10));
}
Assumptions
Often, there are variables outside of a test that is beyond your control. But the test assumes to be true. When an assumption fails, it shouldn’t necessarily mean the test fails. For this purpose, JUnit adds assumeThat
, which you may import like so:
import static org.junit.Assume.*;
Then in our tests, we can verify assumptions before our assertions. For example:
assumeThat(File.separatorChar, is('/'));
When an assumption fails, the test is either marked as “passing” or “ignored,” depending on the version of JUnit.
Assumptions can be combined with either a Parameterized test or Theory to create tests that cover a wide variety of situations.
Parameterized tests
In testing, very often we want to test something with a wide variety of input values. Whether we call it a smoke test, white box, black box, or gray box testing, the testing solution remains the same. For this purpose, JUnit added the concept of a Parameterized test.
By using a few annotations, we can define a list of values to be used for multiple runs of the same tests.
/* imports... */
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class) //1
public class BookTest {
@Parameter public Integer number; //2
@Parameters(name = "{index}: testForNumber({0})") //3
public static List<Integer> getNumbers() {
return Arrays.asList(1, 2, 3, 5, 10, 20, 49, 50, 51);
}
-
Add the
@RunWith
annotation, and specify the Parameterized test runner that should be used by this Test class. -
Parameters should be declared public and annotated with
@Parameter
. If you prefer, you could add a constructor with parameters instead. -
One method should be defined as
public static
and annotated with@Parameters
and return a Collection or array of values to use as parameters. Thename
specified by this annotation will be used to label every execution of each test with {index
} replaced by the index of parameters (starting at 0), and {#
} replaced by the relevant parameter.
We can specify multiple parameters with the @Parameter
annotation by including an index for each parameter as follows:
@Parameter(0) //1
public Integer number;
@Parameter(1) //2
public Boolean single;
@Parameters(name = "{index}: testFor({0}, {1})") //3
public static List getValues() {
return Arrays.asList(new Object[][] {{1, true}, {2, false}});
}
- Specify the first parameter with index zero.
- Specify the second parameter.
- Then, specify the format of the test name using those indexes.
We can provide multiple values for parameters by using a list of Object arrays as shown above. Finally, we can specify any number of tests annotated with @Test
by using the defined parameters. By using assumptions, we can limit some tests to a subset of parameter values.
Get hands-on with 1400+ tech skills courses.