Noah Iarrobino
Noah Iarrobino

Reputation: 1543

Passing int array in ParameterizedTest in java

I am trying to pass in an array for testing a certain algorithm, but the arrays seem to not be passed correctly or at all. I manually tested the algorithm so I know it works as it's supposed to. How can I pass arrays in for testing in JUnit 5?

@ParameterizedTest
@CsvSource(value = {"[13,14,65,456,31,83],[1331,65456]"})
public void palindromeCombos(int[] input, int[] expected){
    Palindrome pal = new Palindrome();
    List<Integer> actual = pal.allPalindromes(input);
    int[] result = new int[actual.size()];
    for(int i = 0; i < actual.size(); i++){
         result[i] = actual.get(i);
    }
    Assertions.assertArrayEquals(expected, result);    
}

Upvotes: 5

Views: 7642

Answers (2)

Mureinik
Mureinik

Reputation: 311308

Pablo's Answer is correct, of course, but personally I'm not a fan of parsing strings if I don't absolutely have to. Another approach could be to use a MethodSource instead, and explicitly provide the arguments you need:

public static Stream<Arguments> palindromeCombos() {
    return Stream.of(
        Arguments.of(new int[]{13, 14, 65, 456, 31, 83}, new int[]{1331, 65456}));
}

@ParameterizedTest
@MethodSource
public void palindromeCombos(int[] input, int[] expected) {
    // Test logic...
}

Upvotes: 11

Since there is not implicit conversion for arrays, you can use explicit conversion, first you need to declare you converter class:

    class IntArrayConverter implements ArgumentConverter {

        @Override
        public Object convert(Object source, ParameterContext context)
                throws ArgumentConversionException {
            if (!(source instanceof String)) {
                throw new IllegalArgumentException(
                        "The argument should be a string: " + source);
            }
            try {
                return Arrays.stream(((String) source).split(",")).mapToInt(Integer::parseInt).toArray();
            } catch (Exception e) {
                e.printStackTrace();
                throw new IllegalArgumentException("Failed to convert", e);
            }
        }
    }

Then you can use it in your test:

    @ParameterizedTest
    @CsvSource(value = {
            "13,14,65,456,31,83;1331,65456",
            "1,2,3,4,5,6;10,20"}, delimiterString = ";")
    public void palindromeCombos(@ConvertWith(IntArrayConverter.class) int[] input,
                                 @ConvertWith(IntArrayConverter.class) int[] expected) {
        System.out.println(Arrays.toString(input));
        System.out.println(Arrays.toString(expected));
    }

Notice that I removed the [] from the CsvSource and changed the delimiter to ;, so the arrays are expressed by a list of integers separated by comma. If you want you can keep the format you had and handle it in the converter class. For those two examples the output is:

[13, 14, 65, 456, 31, 83]
[1331, 65456]

[1, 2, 3, 4, 5, 6]
[10, 20]

If you need further information you can check this post: https://www.baeldung.com/parameterized-tests-junit-5

Upvotes: 4

Related Questions