java Junit5@ParameterizedTest如何将数组作为参数之一传递

kninwzqo  于 2023-01-07  发布在  Java
关注(0)|答案(3)|浏览(263)

我有一个测试,我想在其中传递三个参数:
1.字符串
1.枚举
1.字符串数组
示例:

@ParameterizedTest
    @CsvSource({
            "/path/to/first/file.xlsx, FIRST, {THIRD PARAMETER SHOULD BE ARRAY OF STRINGS}",
            "/path/to/second/file.xlsx, SECOND, {THIRD PARAMETER SHOULD BE ARRAY OF STRINGS}"})
    void uploadFile(String path, FileType type, String[] errors) {
        HttpEntity httpEntity = prepareFileUploadEntity(path, type);

        ResponseEntity<ArrayList> response = getRestTemplate(AppRole.USER).exchange(UPLOAD_URL, HttpMethod.POST, httpEntity, ArrayList.class);

        assertNotNull(response);
        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
        assertEquals(errors.length, response.getBody().size());
        for (String error : errors) {
            assertTrue(response.getBody().contains(error));
        }
    }

我怎样才能把第三个参数作为一个字符串数组来传递呢,因为现在我遇到了第三个参数无法解析的错误:

org.junit.jupiter.api.extension.ParameterResolutionException: Error resolving parameter at index 2
bkkx9g8r

bkkx9g8r1#

@CsvSource使用隐式转换将CSV值转换为基元、枚举或日期。对于其他类型(如数组),需要显式转换。
假设您有一个格式类似@CsvSource("abc, 123, 'foo, bar'")的CSV注解,您可以实现一个如下所示的参数转换器,将最后一个CSV列视为一个数组:

import org.junit.jupiter.params.converter.ArgumentConversionException;
import org.junit.jupiter.params.converter.SimpleArgumentConverter;

public class StringArrayConverter extends SimpleArgumentConverter {

    @Override
    protected Object convert(Object source, Class<?> targetType) throws ArgumentConversionException {
        if (source instanceof String && String[].class.isAssignableFrom(targetType)) {
            return ((String) source).split("\\s*,\\s*");
        } else {
            throw new IllegalArgumentException("Conversion from " + source.getClass() + " to "
                                               + targetType + " not supported.");
        }
    }

}

然后可以在第三个参数上使用该转换器:

@ParameterizedTest
@CsvSource("abc, 123, 'foo, bar'")
void test(String column1, int column2, @ConvertWith(StringArrayConverter.class) String[] column3) {
    assertEquals(column1, "abc");
    assertEquals(column2, 123);
    assertEquals(column3[0], "foo");
    assertEquals(column3[1], "bar");
}
2ul0zpep

2ul0zpep2#

小校正,in

return ((String) source).split("\\s*,\\s*");

应为不同的符号(例如'; ')而不是','
那么在测试中应该是

@ParameterizedTest
@CsvSource("abc, 123, foo; bar")

对我有效的最终版本:

import org.junit.jupiter.params.converter.ArgumentConversionException;
import org.junit.jupiter.params.converter.SimpleArgumentConverter;

public class StringArrayConverter extends SimpleArgumentConverter {

    @Override
    protected Object convert(Object source, Class<?> targetType) throws ArgumentConversionException {
        if (source instanceof String && String[].class.isAssignableFrom(targetType)) {
            return ((String) source).split("\\s*;\\s*");
        } else {
            throw new IllegalArgumentException("Conversion from " + source.getClass() + " to "
                                               + targetType + " not supported.");
        }
    }

}

试验:

@ParameterizedTest
@CsvSource("abc, 123, foo; bar")
void test(String column1, int column2, @ConvertWith(StringArrayConverter.class) String[] column3) {
    assertEquals(column1, "abc");
    assertEquals(column2, 123);
    assertEquals(column3[0], "foo");
    assertEquals(column3[1], "bar");
}
dfddblmv

dfddblmv3#

你可以很容易地做这样的事情:

@DisplayName("Should rotate successfully")
@ParameterizedTest()
@CsvSource({
        "'[0, 0, 0]', 5, '[0, 0, 0]', false",
})
void givenAnArrayAndAShiftSize_ShouldSuccesfullyRotateOrReturnFalse(String arrayStr, int shiftSize,
        String expectedArrayStr, boolean expecetedRotated) {

    var window = Arrays.asList(arrayStr.replace("[", "").replace("]", "").split(","))
            .stream()
            .mapToLong(c -> Long.parseLong(c.toString().trim()))
            .toArray();

    var result = Arrays.asList(expectedArrayStr.replace("[", "").replace("]", "").split(","))
            .stream()
            .mapToLong(c -> Long.parseLong(c.toString().trim()))
            .toArray();

    var rotated = Utils.shiftIfSizeIsValid(window, shiftSize);

    assertEquals(expecetedRotated, rotated);

    for (int i = 0; i < window.length; i++) {
        assertEquals(result[i], window[i]);
    }
}

它更简单,可读性更强。

相关问题