Skip to content

Commit 3df85c7

Browse files
committed
Migrate parameterized tests in spring-core
This commit migrates parameterized tests in spring-core using the "composed @ParameterizedTest" approach. This approach is reused in follow-up commits for the migration of the remaining modules. For a concrete example, see AbstractDataBufferAllocatingTests and its subclasses (e.g., DataBufferTests). Specifically, AbstractDataBufferAllocatingTests declares a custom @ParameterizedDataBufferAllocatingTest annotation that is meta-annotated with @ParameterizedTest and @MethodSource("org.springframework.core.io.buffer.AbstractDataBufferAllocatingTests#dataBufferFactories()"). Individual methods in concrete subclasses are then annotated with @ParameterizedDataBufferAllocatingTest instead of @ParameterizedTest or @test. The approach makes the migration from JUnit 4 to JUnit Jupiter rather straightforward; however, there is one major downside. The arguments for a @ParameterizedTest test method can only be accessed by the test method itself. It is not possible to access them in an @beforeeach method (see junit-team/junit-framework#944). Consequently, we are forced to declare the parameters in each such method and delegate to a custom "setup" method. Although this is a bit cumbersome, I feel it is currently the best way to achieve fine grained parameterized tests within our test suite without implementing a custom TestTemplateInvocationContextProvider for each specific use case. Once junit-team/junit-framework#878 is resolved, we should consider migrating to parameterized test classes. See gh-23451
1 parent 32cc32f commit 3df85c7

File tree

9 files changed

+528
-317
lines changed

9 files changed

+528
-317
lines changed

spring-core/src/test/java/org/springframework/core/LocalVariableTableParameterNameDiscovererTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import java.lang.reflect.Method;
2323
import java.util.Date;
2424

25-
import org.junit.Ignore;
25+
import org.junit.jupiter.api.Disabled;
2626
import org.junit.jupiter.api.Test;
2727

2828
import org.springframework.tests.sample.objects.TestObject;
@@ -203,7 +203,7 @@ public void generifiedClass() throws Exception {
203203
assertThat(names.length).isEqualTo(0);
204204
}
205205

206-
@Ignore("Ignored because Ubuntu packages OpenJDK with debug symbols enabled. See SPR-8078.")
206+
@Disabled("Ignored because Ubuntu packages OpenJDK with debug symbols enabled. See SPR-8078.")
207207
@Test
208208
public void classesWithoutDebugSymbols() throws Exception {
209209
// JDK classes don't have debug information (usually)
Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,57 +16,49 @@
1616

1717
package org.springframework.core.io.buffer;
1818

19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
1923
import java.nio.charset.StandardCharsets;
2024
import java.time.Duration;
2125
import java.time.Instant;
2226
import java.util.Arrays;
2327
import java.util.List;
2428
import java.util.function.Consumer;
29+
import java.util.stream.Stream;
2530

2631
import io.netty.buffer.ByteBufAllocator;
2732
import io.netty.buffer.PoolArenaMetric;
2833
import io.netty.buffer.PooledByteBufAllocator;
2934
import io.netty.buffer.PooledByteBufAllocatorMetric;
3035
import io.netty.buffer.UnpooledByteBufAllocator;
31-
import org.junit.Rule;
32-
import org.junit.rules.Verifier;
33-
import org.junit.runner.RunWith;
34-
import org.junit.runners.Parameterized;
36+
import org.junit.jupiter.api.extension.AfterEachCallback;
37+
import org.junit.jupiter.api.extension.RegisterExtension;
38+
import org.junit.jupiter.params.ParameterizedTest;
39+
import org.junit.jupiter.params.provider.Arguments;
40+
import org.junit.jupiter.params.provider.MethodSource;
3541
import reactor.core.publisher.Mono;
3642

3743
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
3844

3945
import static org.assertj.core.api.Assertions.assertThat;
46+
import static org.junit.jupiter.params.provider.Arguments.arguments;
4047

4148
/**
4249
* Base class for tests that read or write data buffers with a rule to check
4350
* that allocated buffers have been released.
4451
*
4552
* @author Arjen Poutsma
4653
* @author Rossen Stoyanchev
54+
* @author Sam Brannen
4755
*/
48-
@RunWith(Parameterized.class)
49-
public abstract class AbstractDataBufferAllocatingTestCase {
50-
51-
@Parameterized.Parameter
52-
public DataBufferFactory bufferFactory;
53-
54-
@Parameterized.Parameters(name = "{0}")
55-
public static Object[][] dataBufferFactories() {
56-
return new Object[][] {
57-
{new NettyDataBufferFactory(new UnpooledByteBufAllocator(true))},
58-
{new NettyDataBufferFactory(new UnpooledByteBufAllocator(false))},
59-
// disable caching for reliable leak detection, see https://github.com/netty/netty/issues/5275
60-
{new NettyDataBufferFactory(new PooledByteBufAllocator(true, 1, 1, 8192, 11, 0, 0, 0, true))},
61-
{new NettyDataBufferFactory(new PooledByteBufAllocator(false, 1, 1, 8192, 11, 0, 0, 0, true))},
62-
{new DefaultDataBufferFactory(true)},
63-
{new DefaultDataBufferFactory(false)}
56+
public abstract class AbstractDataBufferAllocatingTests {
6457

65-
};
66-
}
58+
@RegisterExtension
59+
AfterEachCallback leakDetector = context -> verifyAllocations();
6760

68-
@Rule
69-
public final Verifier leakDetector = new LeakDetector();
61+
protected DataBufferFactory bufferFactory;
7062

7163

7264
protected DataBuffer createDataBuffer(int capacity) {
@@ -93,8 +85,7 @@ protected void release(DataBuffer... buffers) {
9385

9486
protected Consumer<DataBuffer> stringConsumer(String expected) {
9587
return dataBuffer -> {
96-
String value =
97-
DataBufferTestUtils.dumpString(dataBuffer, StandardCharsets.UTF_8);
88+
String value = DataBufferTestUtils.dumpString(dataBuffer, StandardCharsets.UTF_8);
9889
DataBufferUtils.release(dataBuffer);
9990
assertThat(value).isEqualTo(expected);
10091
};
@@ -150,12 +141,29 @@ private static long getAllocations(List<PoolArenaMetric> metrics) {
150141
}
151142

152143

153-
protected class LeakDetector extends Verifier {
144+
@Retention(RetentionPolicy.RUNTIME)
145+
@Target(ElementType.METHOD)
146+
@ParameterizedTest(name = "{0}")
147+
@MethodSource("org.springframework.core.io.buffer.AbstractDataBufferAllocatingTests#dataBufferFactories()")
148+
public @interface ParameterizedDataBufferAllocatingTest {
149+
}
154150

155-
@Override
156-
public void verify() {
157-
AbstractDataBufferAllocatingTestCase.this.verifyAllocations();
158-
}
151+
public static Stream<Arguments> dataBufferFactories() {
152+
return Stream.of(
153+
arguments("NettyDataBufferFactory - UnpooledByteBufAllocator - preferDirect = true",
154+
new NettyDataBufferFactory(new UnpooledByteBufAllocator(true))),
155+
arguments("NettyDataBufferFactory - UnpooledByteBufAllocator - preferDirect = false",
156+
new NettyDataBufferFactory(new UnpooledByteBufAllocator(false))),
157+
// disable caching for reliable leak detection, see https://github.com/netty/netty/issues/5275
158+
arguments("NettyDataBufferFactory - PooledByteBufAllocator - preferDirect = true",
159+
new NettyDataBufferFactory(new PooledByteBufAllocator(true, 1, 1, 4096, 2, 0, 0, 0, true))),
160+
arguments("NettyDataBufferFactory - PooledByteBufAllocator - preferDirect = false",
161+
new NettyDataBufferFactory(new PooledByteBufAllocator(false, 1, 1, 4096, 2, 0, 0, 0, true))),
162+
arguments("DefaultDataBufferFactory - preferDirect = true",
163+
new DefaultDataBufferFactory(true)),
164+
arguments("DefaultDataBufferFactory - preferDirect = false",
165+
new DefaultDataBufferFactory(false))
166+
);
159167
}
160168

161169
}

0 commit comments

Comments
 (0)