Tuesday 3 August 2021

Junit5: Arguments Aggregation

By default, each argument provided to a @ParameterizedTest method corresponds to a single method parameter. Suppose, if a test require need N arguments, test method signature should have N parameters. If number of inputs are more, then we need to supply a large number of arguments can lead to large method signatures.

 

We can solve above problem using Arguments Aggregation.

 

Aggregate arguments using ArgumentsAccessor

We can use ArgumentsAccessor instead of multiple arguments. ArgumentsAccessor aggregates a set of arguments for a given invocation of a parameterized test and provides convenience methods for accessing those arguments in a type-safe manner with support for automatic type conversion.

 

Example

@ParameterizedTest
@CsvSource({ 
			"Sailu, PTR, FEMALE, 1989-08-20", 
			"Ram, Gurram, MALE, 1990-01-22"
		})
void testWithArgumentsAccessor(ArgumentsAccessor arguments) {
	Person person = new Person(arguments.getString(0), arguments.getString(1), arguments.get(2, Gender.class),
			arguments.get(3, LocalDate.class));

	if (person.getFirstName().equals("Sailu")) {
		assertEquals(Gender.FEMALE, person.getGender());
		assertEquals("PTR", person.getLastName());
		assertEquals(1989, person.getDateOfBirth().getYear());
	} else {
		assertEquals(Gender.MALE, person.getGender());
		assertEquals("Ram", person.getFirstName());
		assertEquals("Gurram", person.getLastName());
		assertEquals(1990, person.getDateOfBirth().getYear());
	}

}

 

Find the below working application.

 

Gender.java

package com.sample.app.model;

public enum Gender {
	FEMALE, MALE

}

Person.java

package com.sample.app.model;

import java.time.LocalDate;

public class Person {
	private String firstName;
	private String lastName;
	private Gender gender;
	private LocalDate dateOfBirth;

	public Person(String firstName, String lastName, Gender gender, LocalDate dateOfBirth) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.gender = gender;
		this.dateOfBirth = dateOfBirth;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Gender getGender() {
		return gender;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	public LocalDate getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(LocalDate dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

}


ArgumentAccessorDemo.java

package com.sample.app;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.LocalDate;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.aggregator.ArgumentsAccessor;
import org.junit.jupiter.params.provider.CsvSource;

import com.sample.app.model.Gender;
import com.sample.app.model.Person;

public class ArgumentAccessorDemo {
	
	@ParameterizedTest
	@CsvSource({ 
				"Sailu, PTR, FEMALE, 1989-08-20", 
				"Ram, Gurram, MALE, 1990-01-22"
			})
	void testWithArgumentsAccessor(ArgumentsAccessor arguments) {
		Person person = new Person(arguments.getString(0), arguments.getString(1), arguments.get(2, Gender.class),
				arguments.get(3, LocalDate.class));

		if (person.getFirstName().equals("Sailu")) {
			assertEquals(Gender.FEMALE, person.getGender());
			assertEquals("PTR", person.getLastName());
			assertEquals(1989, person.getDateOfBirth().getYear());
		} else {
			assertEquals(Gender.MALE, person.getGender());
			assertEquals("Ram", person.getFirstName());
			assertEquals("Gurram", person.getLastName());
			assertEquals(1990, person.getDateOfBirth().getYear());
		}

	}
	
}


Junit Test results




In my next post, I will explain how to implement custom aggregators.

 

 

  

Previous                                                    Next                                                    Home

No comments:

Post a Comment