Junit5 @ParameterizedTest如何将数组作为参数

时间:2017-10-20 12:49:13

标签: java spring-boot integration-testing resttemplate junit5

我有一个测试,我想传递三个参数:

  1. 字符串
  2. 枚举
  3. 字符串数组
  4. 示例:

    @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
    

2 个答案:

答案 0 :(得分:4)

@CsvSource使用implicit conversion将CSV值转换为基元,枚举或日期。对于像阵列这样的其他类型,您需要explicit conversion

假设您使用@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");
}

答案 1 :(得分:0)

小修正,

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");
}