Skip to content

Commit dad11e9

Browse files
committed
Test exception handling for parameter conversion and aggregation
Issue: #1370
1 parent 50a3d6d commit dad11e9

File tree

4 files changed

+97
-14
lines changed

4 files changed

+97
-14
lines changed

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedTestParameterResolver.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,7 @@ private Object convert(ParameterContext parameterContext) {
9393
return argumentConverter.convert(argument, parameterContext);
9494
}
9595
catch (Exception ex) {
96-
String message = "Error resolving parameter at index " + parameterContext.getIndex();
97-
if (StringUtils.isNotBlank(ex.getMessage())) {
98-
message += ": " + ex.getMessage();
99-
}
100-
throw new ParameterResolutionException(message, ex);
96+
throw parameterResolutionException("Error converting parameter", ex, parameterContext);
10197
}
10298
}
10399

@@ -118,12 +114,17 @@ private Object aggregateSafely(Class<? extends ArgumentsAggregator> clazz, Argum
118114
return aggregator.aggregateArguments(accessor, parameterContext);
119115
}
120116
catch (Exception ex) {
121-
String message = "Error aggregating arguments for parameter at index " + parameterContext.getIndex();
122-
if (StringUtils.isNotBlank(ex.getMessage())) {
123-
message += ": " + ex.getMessage();
124-
}
125-
throw new ParameterResolutionException(message, ex);
117+
throw parameterResolutionException("Error aggregating arguments for parameter", ex, parameterContext);
126118
}
127119
}
128120

121+
private ParameterResolutionException parameterResolutionException(String message, Exception cause,
122+
ParameterContext context) {
123+
String fullMessage = message + " at index " + context.getIndex();
124+
if (StringUtils.isNotBlank(cause.getMessage())) {
125+
fullMessage += ": " + cause.getMessage();
126+
}
127+
return new ParameterResolutionException(fullMessage, cause);
128+
}
129+
129130
}

junit-jupiter-params/src/test/java/org/junit/jupiter/params/ParameterizedTestIntegrationTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
package org.junit.jupiter.params;
1212

13+
import static org.assertj.core.api.Assertions.allOf;
1314
import static org.assertj.core.api.Assertions.assertThat;
1415
import static org.assertj.core.api.Assertions.fail;
1516
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
@@ -20,6 +21,7 @@
2021
import static org.junit.platform.engine.test.event.ExecutionEventConditions.event;
2122
import static org.junit.platform.engine.test.event.ExecutionEventConditions.finishedWithFailure;
2223
import static org.junit.platform.engine.test.event.ExecutionEventConditions.test;
24+
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.isA;
2325
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.message;
2426
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
2527

@@ -37,6 +39,7 @@
3739
import org.junit.jupiter.api.TestInfo;
3840
import org.junit.jupiter.api.extension.ExtensionContext;
3941
import org.junit.jupiter.api.extension.ParameterContext;
42+
import org.junit.jupiter.api.extension.ParameterResolutionException;
4043
import org.junit.jupiter.engine.JupiterTestEngine;
4144
import org.junit.jupiter.params.converter.ArgumentConversionException;
4245
import org.junit.jupiter.params.converter.ArgumentConverter;
@@ -224,6 +227,15 @@ void failsContainerOnEmptyName() {
224227
finishedWithFailure(message(value -> value.contains("must be declared with a non-empty name")))));
225228
}
226229

230+
@Test
231+
void reportsExceptionForErroneousConverter() {
232+
List<ExecutionEvent> executionEvents = execute(
233+
selectMethod(TestCase.class, "testWithErroneousConverter", Object.class.getName()));
234+
assertThat(executionEvents) //
235+
.haveExactly(1, event(test(), finishedWithFailure(allOf(isA(ParameterResolutionException.class), //
236+
message("Error converting parameter at index 0: something went horribly wrong")))));
237+
}
238+
227239
private List<ExecutionEvent> execute(DiscoverySelector... selectors) {
228240
return ExecutionEventRecorder.execute(new JupiterTestEngine(), request().selectors(selectors).build());
229241
}
@@ -278,6 +290,12 @@ void testWithEmptyMethodSource(String argument) {
278290
fail(argument);
279291
}
280292

293+
@ParameterizedTest
294+
@ValueSource(ints = 42)
295+
void testWithErroneousConverter(@ConvertWith(ErroneousConverter.class) Object ignored) {
296+
fail("this should never be called");
297+
}
298+
281299
static Stream<Arguments> testWithEmptyMethodSource() {
282300
return Stream.of(Arguments.of("empty method source"));
283301
}
@@ -394,6 +412,14 @@ public Object convert(Object source, ParameterContext context) throws ArgumentCo
394412
}
395413
}
396414

415+
private static class ErroneousConverter implements ArgumentConverter {
416+
417+
@Override
418+
public Object convert(Object source, ParameterContext context) throws ArgumentConversionException {
419+
throw new ArgumentConversionException("something went horribly wrong");
420+
}
421+
}
422+
397423
static class Book {
398424

399425
private final String title;

junit-jupiter-params/src/test/java/org/junit/jupiter/params/aggregator/AggregatorIntegrationTests.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,42 @@
1111
package org.junit.jupiter.params.aggregator;
1212

1313
import static java.util.stream.Collectors.toMap;
14+
import static org.assertj.core.api.Assertions.allOf;
1415
import static org.assertj.core.api.Assertions.assertThat;
1516
import static org.assertj.core.api.Assertions.entry;
1617
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
1718
import static org.junit.jupiter.api.Assertions.assertEquals;
1819
import static org.junit.jupiter.api.Assertions.assertNull;
20+
import static org.junit.jupiter.api.Assertions.fail;
21+
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod;
22+
import static org.junit.platform.engine.test.event.ExecutionEventConditions.event;
23+
import static org.junit.platform.engine.test.event.ExecutionEventConditions.finishedWithFailure;
24+
import static org.junit.platform.engine.test.event.ExecutionEventConditions.test;
25+
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.isA;
26+
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.message;
27+
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
1928

2029
import java.lang.annotation.ElementType;
2130
import java.lang.annotation.Retention;
2231
import java.lang.annotation.RetentionPolicy;
2332
import java.lang.annotation.Target;
2433
import java.time.LocalDate;
34+
import java.util.List;
2535
import java.util.Map;
2636
import java.util.stream.IntStream;
2737

38+
import org.junit.jupiter.api.Test;
2839
import org.junit.jupiter.api.TestInfo;
2940
import org.junit.jupiter.api.extension.ParameterContext;
41+
import org.junit.jupiter.api.extension.ParameterResolutionException;
42+
import org.junit.jupiter.engine.JupiterTestEngine;
3043
import org.junit.jupiter.params.ParameterizedTest;
3144
import org.junit.jupiter.params.provider.CsvSource;
45+
import org.junit.jupiter.params.provider.ValueSource;
3246
import org.junit.platform.commons.util.Preconditions;
47+
import org.junit.platform.engine.DiscoverySelector;
48+
import org.junit.platform.engine.test.event.ExecutionEvent;
49+
import org.junit.platform.engine.test.event.ExecutionEventRecorder;
3350

3451
/**
3552
* Integration tests for {@link ArgumentsAccessor}, {@link AggregateWith},
@@ -148,6 +165,15 @@ void nullAggregator(@AggregateWith(NullAggregator.class) Person person) {
148165
assertNull(person);
149166
}
150167

168+
@Test
169+
void reportsExceptionForErroneousAggregator() {
170+
List<ExecutionEvent> executionEvents = execute(
171+
selectMethod(ErroneousTestCases.class, "testWithErroneousAggregator", Object.class.getName()));
172+
assertThat(executionEvents) //
173+
.haveExactly(1, event(test(), finishedWithFailure(allOf(isA(ParameterResolutionException.class), //
174+
message("Error aggregating arguments for parameter at index 0: something went horribly wrong")))));
175+
}
176+
151177
private void testPersonAggregator(Person person) {
152178
if (person.firstName.equals("Jane")) {
153179
assertEquals("Jane Doe", person.getFullName());
@@ -168,6 +194,10 @@ private void testAddressAggegator(Address address) {
168194
assertEquals(30318, address.zipCode);
169195
}
170196

197+
private List<ExecutionEvent> execute(DiscoverySelector... selectors) {
198+
return ExecutionEventRecorder.execute(new JupiterTestEngine(), request().selectors(selectors).build());
199+
}
200+
171201
// -------------------------------------------------------------------------
172202

173203
static class Person {
@@ -281,4 +311,20 @@ public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext co
281311
}
282312
}
283313

314+
static class ErroneousAggregator implements ArgumentsAggregator {
315+
@Override
316+
public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context)
317+
throws ArgumentsAggregationException {
318+
throw new ArgumentsAggregationException("something went horribly wrong");
319+
}
320+
}
321+
322+
static class ErroneousTestCases {
323+
@ParameterizedTest
324+
@ValueSource(ints = 42)
325+
void testWithErroneousAggregator(@AggregateWith(ErroneousAggregator.class) Object ignored) {
326+
fail("this should never be called");
327+
}
328+
}
329+
284330
}

junit-jupiter-params/src/test/java/org/junit/jupiter/params/aggregator/ArgumentsAccessorTests.java renamed to junit-jupiter-params/src/test/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessorTests.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,29 @@
2424
import org.junit.platform.commons.util.PreconditionViolationException;
2525

2626
/**
27-
* Unit tests for {@link ArgumentsAccessor}.
27+
* Unit tests for {@link DefaultArgumentsAccessor}.
2828
*
2929
* @since 5.2
3030
*/
31-
class ArgumentsAccessorTests {
31+
class DefaultArgumentsAccessorTests {
3232

3333
@Test
34-
void preconditions() {
34+
void argumentsMustNotBeNull() {
3535
assertThrows(PreconditionViolationException.class, () -> new DefaultArgumentsAccessor((Object[]) null));
36+
}
3637

38+
@Test
39+
void indexMustNotBeNegative() {
3740
ArgumentsAccessor arguments = new DefaultArgumentsAccessor(1, 2);
3841
Exception exception = assertThrows(PreconditionViolationException.class, () -> arguments.get(-1));
39-
assertThat(exception.getMessage()).isEqualTo("index must be >= 0 and < 2");
42+
assertThat(exception.getMessage()).containsSubsequence("index must be", ">= 0");
43+
}
44+
45+
@Test
46+
void indexMustBeSmallerThanLength() {
47+
ArgumentsAccessor arguments = new DefaultArgumentsAccessor(1, 2);
48+
Exception exception = assertThrows(PreconditionViolationException.class, () -> arguments.get(2));
49+
assertThat(exception.getMessage()).containsSubsequence("index must be", "< 2");
4050
}
4151

4252
@Test

0 commit comments

Comments
 (0)