Reputation: 951
I have a test in which I want to pass three parameters:
Example:
@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));
}
}
How can I pass the third parameter as an array of strings, cause now I have the error that third parameter can`t be resolved:
org.junit.jupiter.api.extension.ParameterResolutionException: Error resolving parameter at index 2
Upvotes: 13
Views: 17525
Reputation: 1274
You can easily do something like this:
@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]);
}
}
It is simpler and more readable.
Upvotes: 1
Reputation: 951
Small correction, in
return ((String) source).split("\\s*,\\s*");
should be a different sign (e.g. ';') instead of ','
Then in test should be
@ParameterizedTest
@CsvSource("abc, 123, foo; bar")
Final version which works for me:
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.");
}
}
}
Test:
@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");
}
Upvotes: 5
Reputation: 29949
@CsvSource
uses implicit conversion to convert CSV values to primitives, Enums or Dates. For other types like Arrays, you need explicit conversion.
Assuming you have a CSV annotation in a format like @CsvSource("abc, 123, 'foo, bar'")
, you can implement an argument converter like this to treat the last CSV column as an array:
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.");
}
}
}
Then you can use that converter on the third argument:
@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");
}
Upvotes: 24