Junit 5 @TestFactory

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')
}

follow us on