|
Project Information
Members
Featured
Downloads
|
News
This project adds a new runner to JUnit and provides much easier and readable parameterised tests for JUnit >=4.5. Main differences to standard JUnit Parameterized runner:
Specification can be found in JUnitParams Javadoc. You can download JUnitParams from here, from the Downloads section, or if you have a mave build, add this to your pom.xml: <dependency> <groupId>pl.pragmatists</groupId> <artifactId>JUnitParams</artifactId> <version>0.4.0</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 parameterised 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 $(
$(13, false),
$(17, false),
$(18, true),
$(22, true)
);
}The $(...) method is defined in JUnitParamsRunner class and is a shortcut for creating an array of Objects from method params. I use it for readability. It's definition looks like this: public static Object[] $(Object... params) { return params; }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 $(
$(13, false),
$(17, false),
$(18, true),
$(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 Person(13), false),
$(new Person(17), false),
$(new Person(18), true),
$(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 Person(25), true),
$(new Person(32), true)
);
}
public static Object[] provideTeens() {
return $(
$(new Person(12), false),
$(new Person(17), false)
);
}
}
|
