JUnit Parameterized Test Example

In this JUnit tutorial, learn to create and execute junit parameterized tests. A parameterized test is normal test, which is executed over and over with again using different test parameters. It helps developer to save time in executing same test with different input types to test function robustness and possibly function boundaries.

1. JUnit Maven Dependency

Below are maven dependencies, we should add in your maven project before testing example code.

<!-- Junit -->
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.11</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit-dep</artifactId>
	<version>4.11</version>
	<scope>test</scope>
</dependency>

2. JUnit parameterized test with constructor arguments

Parameterized test make use of @RunWith annotation along with @Parameters annotations to feed inputs.

2.1. Class to be tested

Below is the test class, we will write test case for.

package corejava.test.junit;

public final class MathUtils 
{
	//Return square of a function
	public static int square(final int number) {
		return number * number;
	}
}

2.2. Parameterized Tests

Lets write the parameterized tests for above math utility class.


package corejava.test.junit;

import java.util.Arrays;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class JunitTestsWithParameters {

	// @Parameters annotation marks this method as parameters provider
	@Parameters(name = "Run #Square of : {0}^2={1}")
	public static Iterable<Object []> data() 
	{
		return Arrays.asList(new Object[][] { { 1, 1 }, 
											{ 2, 4 }, 
											{ 3, 19 }, 
											{ 4, 16 }, 
											{ 5, 25 } });
	}

	// Our two parameters
	private final int input;
	private final int resultExpected;

	// Constructor is initialized with one set of parameters every time
	public JunitTestsWithParameters(final int input, final int result) 
	{
		this.input = input;
		this.resultExpected = result;
	}

	@Test
	public void testUserMapping() {
		// You can use here assert also
		Assert.assertEquals(resultExpected, MathUtils.square(input));
	}
}

Please note that –

  1. We must follow only given way to declare the parameter.
  2. Parameters are passes to class’s constructor to set in variables and thus be available in test cases.
  3. The return type of parameter class is “List []”, data types to be used have been limited to String or primitive value

Now check the program output.

junit-4-test-execution-8886022
Test execution result

3. JUnit parameterized test with field injection

To pass parameters to test, we can pass argument via field injection – rather than constructor arguments as well. In this approach, we declare exact number of fields as input parameters. One parameter per field.

Let’s retest our MathUtils class with field injection. Notice how we replaced constructor with fields annotated with @Parameter annotation.

import org.junit.Assert;
import org.junit.Test;
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)
public class JunitTestsWithFieldInjection {

    @Parameters(name = "Run #Square of : {0}^2={1}")
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][] { { 1, 1 }, { 2, 4 }, { 3, 9 }, { 4, 16 }, { 5, 25 } });
    }

    @Parameter(value = 0)
    public int input;
    
    @Parameter(value = 1)
    public int resultExpected;

    @Test
    public void testSquare() 
    {
        Assert.assertEquals(resultExpected, MathUtils.square(input));
    }
}

3.1. Single field injection

If we have only one field to inject, then we do not need to put value attribute in @Parameter annotation. Default value is always “value=0”.

import org.junit.Assert;
import org.junit.Test;
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)
public class JunitTestsWithParameters {

    @Parameters(name = "Argument number {0} is positive")
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][] { { 0 }, { 1 }, { 2 }, { 3 }, { 4 } });
    }

    @Parameter
    public int input;

    @Test
    public void testPositiveNumber() 
    {
        Assert.assertEquals(true, input >= 0);
    }
}

In this post, we learned to create parameterized tests and run multiple iterations of test with different parameters set. It helps to test method with parameters.

Happy Learning !!

7 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Comments are closed for this article!

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.