Skip to content

Commit d0683b3

Browse files
committed
Add @SpringConversion negative test
1 parent 6cb8a59 commit d0683b3

2 files changed

Lines changed: 83 additions & 1 deletion

File tree

src/test/java/io/github/scordio/tests/junit/converters/JupiterEngineTestKit.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.github.scordio.tests.junit.converters;
1717

18+
import org.junit.platform.engine.DiscoverySelector;
1819
import org.junit.platform.testkit.engine.EngineExecutionResults;
1920
import org.junit.platform.testkit.engine.EngineTestKit;
2021

@@ -24,7 +25,15 @@
2425
class JupiterEngineTestKit {
2526

2627
static EngineExecutionResults executeTestsForClass(Class<?> testClass) {
27-
return EngineTestKit.execute("junit-jupiter", request().selectors(selectClass(testClass)).build());
28+
return executeTestsFor(selectClass(testClass));
29+
}
30+
31+
static EngineExecutionResults executeTestsForClass(String testClass, ClassLoader classLoader) {
32+
return executeTestsFor(selectClass(classLoader, testClass));
33+
}
34+
35+
private static EngineExecutionResults executeTestsFor(DiscoverySelector... selectors) {
36+
return EngineTestKit.execute("junit-jupiter", request().selectors(selectors).build());
2837
}
2938

3039
}

src/test/java/io/github/scordio/tests/junit/converters/SpringConversionIntegrationTests.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,27 @@
1717

1818
import io.github.scordio.junit.converters.SpringConversion;
1919
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.api.extension.ParameterResolutionException;
2021
import org.junit.jupiter.params.ParameterizedTest;
2122
import org.junit.jupiter.params.provider.FieldSource;
23+
import org.junit.jupiter.params.provider.ValueSource;
2224

25+
import java.net.URL;
26+
import java.net.URLClassLoader;
27+
import java.security.CodeSource;
28+
import java.security.ProtectionDomain;
2329
import java.util.List;
2430
import java.util.Map;
31+
import java.util.Set;
32+
import java.util.stream.Collectors;
2533

2634
import static io.github.scordio.tests.junit.converters.JupiterEngineTestKit.executeTestsForClass;
2735
import static org.assertj.core.api.Assertions.assertThat;
2836
import static org.junit.jupiter.params.provider.Arguments.arguments;
37+
import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure;
38+
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.cause;
39+
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.instanceOf;
40+
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.message;
2941

3042
class SpringConversionIntegrationTests {
3143

@@ -104,4 +116,65 @@ void string_to_list(@SpringConversion List<Integer> list, List<Integer> expected
104116

105117
}
106118

119+
@Test
120+
void should_fail_without_spring_core_in_the_classpath() {
121+
ClassLoader classLoader = new SpringFilteringClassLoader();
122+
123+
executeTestsForClass(MissingSpringCoreTestCase.class.getName(), classLoader).testEvents()
124+
.assertStatistics(stats -> stats.started(1).failed(1))
125+
.assertThatEvents()
126+
.haveExactly(1, finishedWithFailure( //
127+
instanceOf(ParameterResolutionException.class), cause( //
128+
instanceOf(NoClassDefFoundError.class),
129+
message("org/springframework/core/convert/ConversionService"))));
130+
}
131+
132+
static class MissingSpringCoreTestCase {
133+
134+
@ParameterizedTest
135+
@ValueSource(strings = "123, 456")
136+
void test(@SuppressWarnings("unused") @SpringConversion List<Integer> list) {
137+
// never called
138+
}
139+
140+
}
141+
142+
private static class SpringFilteringClassLoader extends URLClassLoader {
143+
144+
private static final Set<Class<?>> TARGET_CLASSES = Set.of( //
145+
MissingSpringCoreTestCase.class, SpringConversion.class);
146+
147+
private static final Set<String> TARGET_PACKAGES = TARGET_CLASSES.stream()
148+
.map(Class::getPackageName)
149+
.collect(Collectors.toSet());
150+
151+
private static final URL[] CLASSPATH_URLS = TARGET_CLASSES.stream()
152+
.map(Class::getProtectionDomain)
153+
.map(ProtectionDomain::getCodeSource)
154+
.map(CodeSource::getLocation)
155+
.toArray(URL[]::new);
156+
157+
private static final String SPRING_CORE_PACKAGE = "org.springframework.core";
158+
159+
private SpringFilteringClassLoader() {
160+
super(CLASSPATH_URLS);
161+
}
162+
163+
@Override
164+
public Class<?> loadClass(String name) throws ClassNotFoundException {
165+
synchronized (getClassLoadingLock(name)) {
166+
if (TARGET_PACKAGES.stream().anyMatch(name::startsWith)) {
167+
return findClass(name);
168+
}
169+
170+
if (name.startsWith(SPRING_CORE_PACKAGE)) {
171+
throw new ClassNotFoundException();
172+
}
173+
174+
return super.loadClass(name);
175+
}
176+
}
177+
178+
}
179+
107180
}

0 commit comments

Comments
 (0)