@MethodSource annotation is used to pass complex arguments to the test method.
Step 1: Create a method that produce stream of arguments.
private static Stream<Arguments> provideEmployeeDetails() {
return Stream.of(
Arguments.of(new Employee(1, "Krishna", "Gurram")),
Arguments.of(new Employee(2, "Gopi", "Battu")),
Arguments.of(new Employee(3, "Ram", "Ponnam"))
);
}
Step 2: Specify the method defined in step 1 as method source.
@ParameterizedTest
@MethodSource("provideEmployeeDetails")
void getEmployeeAsStringTest1(Employee emp) {
String expected = emp.getId() + "," + emp.getFirstName() + "," + emp.getLastName();
String actual = EmployeeUtil.getEmployeeAsString(emp);
assertEquals(expected, actual);
}
That’s it you are done.
You can even pass multiple arguments to a test method using stream of arguments.
private static Stream<Arguments> provideEmployeeInfo() {
return Stream.of(
Arguments.of(1, "Krishna", "Gurram"),
Arguments.of(2, "Gopi", "Battu"),
Arguments.of(3, "Ram", "Ponnam")
);
}
@ParameterizedTest
@MethodSource("provideEmployeeInfo")
void getEmployeeAsStringTest2(int id, String firstName, String lastName) {
Employee emp = new Employee(id, firstName, lastName);
String expected = emp.getId() + "," + emp.getFirstName() + "," + emp.getLastName();
String actual = EmployeeUtil.getEmployeeAsString(emp);
assertEquals(expected, actual);
}
Find the below working application.
Employee.java
package com.sample.app;
public class Employee {
private int id;
private String firstName;
private String lastName;
public Employee() {
}
public Employee(int id, String firstName, String lastName) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
EmployeeUtil.java
package com.sample.app.util;
import com.sample.app.Employee;
public class EmployeeUtil {
public static String getEmployeeAsString(Employee emp) {
if(emp == null) {
return "none";
}
return emp.getId()+","+emp.getFirstName()+","+emp.getLastName();
}
}
MethodSourceDemo1.java
package com.sample.app.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import com.sample.app.Employee;
public class MethodSourceDemo1 {
@ParameterizedTest
@MethodSource("provideEmployeeDetails")
void getEmployeeAsStringTest1(Employee emp) {
String expected = emp.getId() + "," + emp.getFirstName() + "," + emp.getLastName();
String actual = EmployeeUtil.getEmployeeAsString(emp);
assertEquals(expected, actual);
}
@ParameterizedTest
@MethodSource("provideEmployeeInfo")
void getEmployeeAsStringTest2(int id, String firstName, String lastName) {
Employee emp = new Employee(id, firstName, lastName);
String expected = emp.getId() + "," + emp.getFirstName() + "," + emp.getLastName();
String actual = EmployeeUtil.getEmployeeAsString(emp);
assertEquals(expected, actual);
}
private static Stream<Arguments> provideEmployeeDetails() {
return Stream.of(
Arguments.of(new Employee(1, "Krishna", "Gurram")),
Arguments.of(new Employee(2, "Gopi", "Battu")),
Arguments.of(new Employee(3, "Ram", "Ponnam"))
);
}
private static Stream<Arguments> provideEmployeeInfo() {
return Stream.of(
Arguments.of(1, "Krishna", "Gurram"),
Arguments.of(2, "Gopi", "Battu"),
Arguments.of(3, "Ram", "Ponnam")
);
}
}
Run 'MethodSourceDemo1' as
junit test, you will see that test methods are executed successfully in junit
window.
If a test method takes only one argument, then you can return a Stream of instances of the parameter type.
@ParameterizedTest
@MethodSource("stringProvider")
void getLengthTest(String input) {
int expectedLength = (input == null) ? -1 : input.length();
int actualLength = getLength(input);
assertEquals(expectedLength, actualLength);
}
static Stream<String> stringProvider() {
return Stream.of("apple", "banana", "Carrot", "Mango");
}
MethodSourceDemo2.java
package com.sample.app;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class MethodSourceDemo2 {
private static int getLength(String str) {
if (str == null) {
return -1;
}
return str.length();
}
@ParameterizedTest
@MethodSource("stringProvider")
void getLengthTest(String input) {
int expectedLength = (input == null) ? -1 : input.length();
int actualLength = getLength(input);
assertEquals(expectedLength, actualLength);
}
static Stream<String> stringProvider() {
return Stream.of("apple", "banana", "Carrot", "Mango");
}
}
When we don't provide a name for the @MethodSource, JUnit will search for a source method with the same name as the test method.
@ParameterizedTest
@MethodSource
void getLengthTest(String input) {
int expectedLength = (input == null) ? -1 : input.length();
int actualLength = getLength(input);
assertEquals(expectedLength, actualLength);
}
static Stream<String> getLengthTest() {
return Stream.of("apple", "banana", "Carrot", "Mango");
}
MethodSourceDemo3.java
package com.sample.app;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class MethodSourceDemo3 {
private static int getLength(String str) {
if (str == null) {
return -1;
}
return str.length();
}
@ParameterizedTest
@MethodSource
void getLengthTest(String input) {
int expectedLength = (input == null) ? -1 : input.length();
int actualLength = getLength(input);
assertEquals(expectedLength, actualLength);
}
static Stream<String> getLengthTest() {
return Stream.of("apple", "banana", "Carrot", "Mango");
}
}
How to specify external factory method as method source?
An external, static factory method can be referenced by providing its fully qualified method name.
@ParameterizedTest
@MethodSource("com.sample.app.util.InputUtil#getStrings")
void getLengthTest(String input) {
int expectedLength = (input == null) ? -1 : input.length();
int actualLength = getLength(input);
assertEquals(expectedLength, actualLength);
}
In the above snippet I specified method source as ‘getStrings’ method defined in InputUtil class.
InputUtil.java
package com.sample.app.util;
import java.util.stream.Stream;
public class InputUtil {
public static Stream<String> getStrings() {
return Stream.of("apple", "banana", "Carrot", "Mango");
}
}
MethodSourceDemo4.java
package com.sample.app;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class MethodSourceDemo4 {
private static int getLength(String str) {
if (str == null) {
return -1;
}
return str.length();
}
@ParameterizedTest
@MethodSource("com.sample.app.util.InputUtil#getStrings")
void getLengthTest(String input) {
int expectedLength = (input == null) ? -1 : input.length();
int actualLength = getLength(input);
assertEquals(expectedLength, actualLength);
}
}
No comments:
Post a Comment