Class ParameterizedTestHelper


  • public class ParameterizedTestHelper
    extends Object
    Test helper for running parameterized tests. Uses AssertJ's SoftAssertions so that all assertion failures can be gathered across a range of inputs (as opposed to failing on the first assertion failure).

    NOTE: When writing new tests, consider instead using JUnit Jupiter's @ParameterizedTest. This class was created from long ago, before JUnit Jupiter existed, and we still have code that uses it. Depending on the specific context, the methods here might end up creating very readable tests.

    See Also:
    ParameterizedTests, JUnit 5 @ParameterizedTest, JUnit 5 Writing Parameterized Tests
    • Constructor Detail

      • ParameterizedTestHelper

        public ParameterizedTestHelper​(org.assertj.core.api.SoftAssertions softly)
        Create a new helper instance.
        Parameters:
        softly - AssertJ soft assertions instance
    • Method Detail

      • expectedResults

        @SafeVarargs
        public static <R> List<R> expectedResults​(R... results)
        Helper method that creates a list of expected results, mainly for readability in tests.
        Type Parameters:
        R - the result object type
        Parameters:
        results - the values to use as expected results in a parameterized test
        Returns:
        a mutable list containing the given values
        See Also:
        ParameterizedTests.inputs(Object[])
      • assertStateChangeResult

        public <T,​R> void assertStateChangeResult​(List<T> inputValues,
                                                        List<R> expectedResults,
                                                        Consumer<T> mutator,
                                                        Supplier<R> resultSupplier)
        Given a list of input values, supply each one to the mutator, and (softly) assert that the result of invoking the resultSupplier matches the expected value in expectedResults. The inputValues and expectedResults are expected to be the same length and that they match at each index, i.e. that expectedResults[N] is the expected result when applying inputValues[N] as the input.

        Example: Suppose you have a Person class that has a setActiveFromString(String) method and a isActive() method; the former is the input mutator function which accepts a String, and the latter is the result function which returns a boolean. You can then write a test like:

         @Test
          void shouldAcceptActiveAsString(SoftAssertions softly) {
              var p = new Person();
              List<String> inputs = inputs("true", "yes", "YES", "false", "no", "NO", "foo", "bar");
              List<Boolean> expected = expectedResults(true, true, true, false, false, false, false, false);
              var testHelper = new ParameterizedTestHelper(softly);
              testHelper.assertStateChangeResult(inputs, expected, p::setActiveFromString, p::isActive);
          }
         
        Note the examples use the input and expectedResults static factory methods for readability, but you can use anything to create the lists.
        Type Parameters:
        T - the input type
        R - the result type
        Parameters:
        inputValues - the inputs
        expectedResults - the expected results
        mutator - the mutator function, e.g. a setter method
        resultSupplier - result function
        See Also:
        ParameterizedTests.inputs(Object[]), expectedResults(Object[])
      • assertExpectedResult

        public <T,​R> void assertExpectedResult​(List<T> inputValues,
                                                     List<R> expectedResults,
                                                     Function<T,​R> function)
        Given a list of input values, supply each one to the function, and (softly) assert that the result of invoking the function matches the expected value in expectedResults. The inputValues and expectedResults are expected to be the same length and that they match at each index, i.e. that expectedResults[N] is the expected result when applying inputValues[N] as the input.

        Example: Assuming there is a SimpleMath utility class with a square function that accepts an integer, a test might look like:

         @Test
          void shouldCalculateSquares(SoftAssertions softly) {
              var inputs = inputs(1, 2, 3, 4, 5);
              var expected = expectedResults(1, 4, 9, 16, 25);
              new ParameterizedTestHelper(softly).assertExpectedResult(inputs, expected, SimpleMath::square);
          }
         
        Note the examples use the input and expectedResults static factory methods for readability, but you can use anything to create the lists.
        Type Parameters:
        T - the input type
        R - the result type
        Parameters:
        inputValues - the inputs
        expectedResults - the expected results
        function - function that accepts a T and produces an R
        See Also:
        ParameterizedTests.inputs(Object[]), expectedResults(Object[])