Skip to content

Commit e749671

Browse files
committed
feat(junit): Fix @WithConfig to be applied at any level
1 parent 8b1580f commit e749671

3 files changed

Lines changed: 27 additions & 14 deletions

File tree

utils/junit-utils/src/main/java/datadog/trace/junit/utils/config/WithConfig.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package datadog.trace.junit.utils.config;
22

3-
import java.lang.annotation.ElementType;
3+
import static java.lang.annotation.ElementType.METHOD;
4+
import static java.lang.annotation.ElementType.TYPE;
5+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
6+
47
import java.lang.annotation.Repeatable;
58
import java.lang.annotation.Retention;
6-
import java.lang.annotation.RetentionPolicy;
79
import java.lang.annotation.Target;
810
import org.junit.jupiter.api.extension.ExtendWith;
911

@@ -27,8 +29,8 @@
2729
* }
2830
* }</pre>
2931
*/
30-
@Retention(RetentionPolicy.RUNTIME)
31-
@Target({ElementType.TYPE, ElementType.METHOD})
32+
@Retention(RUNTIME)
33+
@Target({TYPE, METHOD})
3234
@Repeatable(WithConfigs.class)
3335
@ExtendWith(WithConfigExtension.class)
3436
public @interface WithConfig {

utils/junit-utils/src/main/java/datadog/trace/junit/utils/config/WithConfigExtension.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.lang.reflect.Constructor;
2020
import java.lang.reflect.Field;
2121
import java.lang.reflect.Modifier;
22+
import java.util.ArrayList;
2223
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
@@ -109,12 +110,20 @@ public void afterAll(ExtensionContext context) {
109110
}
110111

111112
private void applyDeclaredConfig(ExtensionContext context) {
112-
// Class-level @WithConfig annotations (supports composed/meta-annotations)
113-
List<WithConfig> classConfigs =
114-
AnnotationSupport.findRepeatableAnnotations(
115-
context.getRequiredTestClass(), WithConfig.class);
116-
for (WithConfig cfg : classConfigs) {
117-
applyConfig(cfg);
113+
// Class-level @WithConfig annotations
114+
// Walk the entire class hierarchy so annotations on superclasses are applied
115+
// (topmost first, then subclass overrides)
116+
Class<?> testClass = context.getRequiredTestClass();
117+
List<Class<?>> hierarchy = new ArrayList<>();
118+
for (Class<?> cls = testClass; cls != null; cls = cls.getSuperclass()) {
119+
hierarchy.add(cls);
120+
}
121+
for (int i = hierarchy.size() - 1; i >= 0; i--) {
122+
List<WithConfig> classConfigs =
123+
AnnotationSupport.findRepeatableAnnotations(hierarchy.get(i), WithConfig.class);
124+
for (WithConfig cfg : classConfigs) {
125+
applyConfig(cfg);
126+
}
118127
}
119128
// Method-level @WithConfig annotations (supports composed/meta-annotations)
120129
context

utils/junit-utils/src/main/java/datadog/trace/junit/utils/config/WithConfigs.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package datadog.trace.junit.utils.config;
22

3-
import java.lang.annotation.ElementType;
3+
import static java.lang.annotation.ElementType.METHOD;
4+
import static java.lang.annotation.ElementType.TYPE;
5+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
6+
47
import java.lang.annotation.Retention;
5-
import java.lang.annotation.RetentionPolicy;
68
import java.lang.annotation.Target;
79
import org.junit.jupiter.api.extension.ExtendWith;
810

911
/** Container annotation for repeatable {@link WithConfig}. */
10-
@Retention(RetentionPolicy.RUNTIME)
11-
@Target({ElementType.TYPE, ElementType.METHOD})
12+
@Retention(RUNTIME)
13+
@Target({TYPE, METHOD})
1214
@ExtendWith(WithConfigExtension.class)
1315
public @interface WithConfigs {
1416
WithConfig[] value();

0 commit comments

Comments
 (0)