-
Notifications
You must be signed in to change notification settings - Fork 149
Quickstart
If you want to see just one simple test class with all main ways to use JUnitParams see here: https://github.com/Pragmatists/JUnitParams/blob/master/src/test/java/junitparams/usage/SamplesOfUsageTest.java
If you have a maven build, add this to your pom.xml:
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
How do you use it? Let's say you (want to) have a class that represents a person:
public class Person {
private int age;
public Person(int age) {
this.age = age;
}
public boolean isAdult() {
return age >= 18;
}
@Override
public String toString() {
return "Person of age: " + age;
}
}
And you want to test it, so you create a test and define a JUnitParamsRunner
for it:
@RunWith(JUnitParamsRunner.class)
public class PersonTest {
...
Now say you want to have a simple parametrised test, that checks if a person of a given age is adult. You can define test parameters as a value of the @Parameters annotation:
@Test
@Parameters({
"17, false",
"22, true" })
public void personIsAdult(int age, boolean valid) throws Exception {
assertThat(new Person(age).isAdult(), is(valid));
}
This is ok if you want to have only a few values, but if you want to have more, you can use a method from the test class to give you the values:
@Test
@Parameters(method = "adultValues")
public void personIsAdult(int age, boolean valid) throws Exception {
assertEquals(valid, new Person(age).isAdult());
}
private Object[] adultValues() {
return new Object[]{
new Object[]{13, false},
new Object[]{17, false},
new Object[]{18, true},
new Object[]{22, true}
};
}
If your test method name is short, like ours here, you can skip the method attribute of the @Parameters
annotation and name your params providing method just like the test method, but prefixed with parametersFor:
@Test
@Parameters
public void personIsAdult(int age, boolean valid) throws Exception {
assertEquals(valid, new Person(age).isAdult());
}
private Object[] parametersForPersonIsAdult() {
return new Object[]{
new Object[]{13, false},
new Object[]{17, false},
new Object[]{18, true},
new Object[]{22, true}
};
}
Isn't giving primitives to a test a bit un-object-oriented? Sure - and there's the stupid constructor call in the test method. So let's skip it by passing the whole Person object to the test class:
@Test
@Parameters
public void isAdult(Person person, boolean valid) throws Exception {
assertThat(person.isAdult(), is(valid));
}
private Object[] parametersForIsAdult() {
return new Object[]{
new Object[]{new Person(13), false},
new Object[]{new Person(17), false},
new Object[]{new Person(18), true},
new Object[]{new Person(22), true}
};
}
Sometimes you may want to externalise the params provider (to test-drive it, or because it's complex and clutters the test class, or because you already have it...). The common use would be when reading the test data/params from a file or a DB. There's obviously a way to do that too:
@Test
@Parameters(source = PersonProvider.class)
public void personIsAdult(Person person, boolean valid) {
assertThat(person.isAdult(), is(valid));
}
And then the PersonProvider
class must have at least one static method that starts with provide and returns Object[]
. Something like this:
public class PersonProvider {
public static Object[] provideAdults() {
return new Object[]{
new Object[]{new Person(25), true},
new Object[]{new Person(32), true}
};
}
public static Object[] provideTeens() {
return new Object[]{
new Object[]{new Person(12), false},
new Object[]{new Person(17), false}
};
}
}