Sometimes we have to test a single method with multiple different outputs, 1 way is to create the same test case multiple times and change the input parameter, but it's a lot of boilerplate and redundant code.
To avoid these situations, Junit 5 provides a Dynamic Test concept. these tests are generated by a factory method at run time. Dynamic Test factory method must be annotated with @TestFactory
annotation.
The Dynamic Test factory method must return Stream, Collection, Iterable, or Collection of DynamicTest instances, any other return type will result in JUnitException
.
package org.wesome.junit5;
import lombok.extern.log4j.Log4j2;
@Log4j2
public class AppleCalculator {
public int addApple(int apple1, int apple2) {
int apple = apple1 + apple2;
log.info("input is {} and {}, after computation output is {}", apple1, apple2, apple);
return apple;
}
}
package org.wesome.junit5;
import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
@Log4j2
class AppleCalculatorTest {
@TestFactory
Collection<DynamicTest> dynamicTestsFromCollection() {
AppleCalculator appleCalculator = new AppleCalculator();
return Arrays.asList(
dynamicTest("1 apple + 1 apple", () -> assertEquals(2, appleCalculator.addApple(1, 1), " 1 apple + 1 apple is 2 apple ")),
dynamicTest("2 apple + 2 apple", () -> assertEquals(4, appleCalculator.addApple(2, 2), " 2 apple + 2 apple is 4 apple "))
);
}
}
plugins {
id 'java'
id 'io.freefair.lombok' version '6.0.0-m2'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}