#java #arrays #junit5 #illegalargumentexception
#java #массивы #junit5 #исключение illegalargumentexception
Вопрос:
Я только начал выполнять упражнение под названием «Two Sum» в LeetCode, и у меня возникли проблемы с тестированием.
Теперь код для упражнения выглядит следующим образом:
public class TwoSumCalculator {
public int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; i ) {
for (int j = i 1; j < numbers.length; j ) {
if (numbers[j] == target - numbers[i]) {
return new int[]{i, j};
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
}
И вот как выглядит мой тест:
class TwoSumCalculatorTest {
TwoSumCalculator twoSumCalculator = new TwoSumCalculator();
@ParameterizedTest
@MethodSource("parameters")
void findIndices(int[] expectedNumbers, int[] inputNumbers, int target) {
int[] resultedNumbers = twoSumCalculator.twoSum(inputNumbers, target);
assertArrayEquals(expectedNumbers, resultedNumbers);
}
private static Stream<Arguments> parameters() {
return Stream.of(
Arguments.of(new int[]{1, 2}, new int[]{3, 2, 4}, 6),
Arguments.of(new int[]{0, 1}, new int[]{2, 7, 11, 15}, 9),
Arguments.of(new int[]{0, 1}, new int[]{3, 3}, 6),
Arguments.of(new IllegalArgumentException("No two sum solution"), new int[]{3, 1, 2}, 6));
}
}
При прохождении первых 3 тестов я получаю следующее сообщение об ошибке с 4-м аргументом:
org.junit.jupiter.api.extension.Исключение ParameterResolutionException: ошибка преобразования параметра с индексом 0: нет неявного преобразования для преобразования объекта типа java.lang.Исключение IllegalArgumentException для ввода [I
Какой был бы лучший способ проверить это?
Ответ №1:
Вместо того, чтобы пытаться параметризовать как успешные, так и неудачные случаи в одном и том же тесте, я бы посоветовал вам протестировать их отдельно. Это позволяет использовать assertThrows
метод для утверждения генерируемых исключений и позволяет избежать необходимости вводить логику в тестовый код.
Что-то вроде:
class TwoSumCalculatorTest {
TwoSumCalculator twoSumCalculator = new TwoSumCalculator();
@ParameterizedTest
@MethodSource("twoSumParameters")
void twoSumSolutions(int[] expectedNumbers, int[] inputNumbers, int target) {
int[] resultedNumbers = twoSumCalculator.twoSum(inputNumbers, target);
assertArrayEquals(expectedNumbers, resultedNumbers);
}
@ParameterizedTest
@MethodSource("noTwoSumParameters")
void noTwoSumSolutions(int[] inputNumbers, int target) {
assertThrows(IllegalArgumentException.class, () -> {
twoSumCalculator.twoSum(inputNumbers, target);
})
}
private static Stream<Arguments> twoSumParameters() {
return Stream.of(
Arguments.of(new int[]{1, 2}, new int[]{3, 2, 4}, 6),
Arguments.of(new int[]{0, 1}, new int[]{2, 7, 11, 15}, 9),
Arguments.of(new int[]{0, 1}, new int[]{3, 3}, 6)
);
private static Stream<Arguments> noTwoSumParameters() {
return Stream.of(
Arguments.of(new int[]{3, 1, 2}, 6)
// Could add more exceptional cases here
);
}
Ответ №2:
Вы могли бы сделать что-то подобное или, возможно, просто провести отдельный тест для случаев, которые вызывают исключения.
@ParameterizedTest
@MethodSource("parameters")
void findIndices(int[] expectedNumbers, int[] inputNumbers, int target, Class expectedException) {
if (expectedException != null) {
assertThrows(expectedException, () -> twoSumCalculator.twoSum(inputNumbers, target));
} else {
int[] resultedNumbers = twoSumCalculator.twoSum(inputNumbers, target);
assertArrayEquals(expectedNumbers, resultedNumbers);
}
}
private static Stream<Arguments> parameters() {
return Stream.of(
Arguments.of(new int[]{1, 2}, new int[]{3, 2, 4}, 6, null),
Arguments.of(new int[]{0, 1}, new int[]{2, 7, 11, 15}, 9, null),
Arguments.of(new int[]{0, 1}, new int[]{3, 3}, 6, null),
Arguments.of(null, new int[]{3, 1, 2}, 6, IllegalArgumentException.class));
}