Skip to content

Commit 9f1699c

Browse files
committed
Validate actual rule object instead of Field#type for @rule
fixes junit-team#1720
1 parent 7167b23 commit 9f1699c

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

src/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java

+10
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ public void validate(FrameworkMember<?> member, Class<? extends Annotation> anno
230230
*/
231231
private static final class FieldMustBeARule implements RuleValidator {
232232
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
233+
if (true) {
234+
// Field type is not validated as field value can still implement the interface
235+
// even in case field type does not.
236+
return;
237+
}
233238
if (!isRuleType(member)) {
234239
errors.add(new ValidationError(member, annotation,
235240
"must implement MethodRule or TestRule."));
@@ -270,6 +275,11 @@ private static final class FieldMustBeATestRule implements RuleValidator {
270275

271276
public void validate(FrameworkMember<?> member,
272277
Class<? extends Annotation> annotation, List<Throwable> errors) {
278+
if (true) {
279+
// Field type is not validated as field value can still implement the interface
280+
// even in case field type does not.
281+
return;
282+
}
273283
if (!isTestRule(member)) {
274284
errors.add(new ValidationError(member, annotation,
275285
"must implement TestRule."));

src/main/java/org/junit/runners/model/TestClass.java

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.junit.Before;
2323
import org.junit.BeforeClass;
2424
import org.junit.internal.MethodSorter;
25+
import org.junit.rules.MethodRule;
26+
import org.junit.rules.TestRule;
2527

2628
/**
2729
* Wraps a class to be run, providing method validation and annotation searching
@@ -249,6 +251,10 @@ public <T> void collectAnnotatedFieldValues(Object test,
249251
Object fieldValue = each.get(test);
250252
if (valueClass.isInstance(fieldValue)) {
251253
consumer.accept(each, valueClass.cast(fieldValue));
254+
} else if (fieldValue != null && (valueClass == TestRule.class || valueClass == MethodRule.class)
255+
&& !(fieldValue instanceof TestRule) && !(fieldValue instanceof MethodRule)) {
256+
throw new IllegalArgumentException(each + " must implement MethodRule or TestRule." +
257+
" Actual type is " + fieldValue.getClass());
252258
}
253259
} catch (IllegalAccessException e) {
254260
throw new RuntimeException(

src/test/java/org/junit/rules/RuleMemberValidatorTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.List;
1111

1212
import org.junit.ClassRule;
13+
import org.junit.Ignore;
1314
import org.junit.Rule;
1415
import org.junit.Test;
1516
import org.junit.runners.model.FrameworkMethod;
@@ -76,6 +77,7 @@ static class NonPublicTestWithClassRule {
7677
* <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
7778
*/
7879
@Test
80+
@Ignore("junit-team/junit4/issues/1720, validation uses actual object value, not just field type")
7981
public void rejectClassRuleThatIsImplementationOfMethodRule() {
8082
TestClass target = new TestClass(TestWithClassRuleIsImplementationOfMethodRule.class);
8183
CLASS_RULE_VALIDATOR.validate(target, errors);
@@ -126,6 +128,7 @@ public Statement apply(Statement base, FrameworkMethod method, Object target) {
126128
* <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
127129
*/
128130
@Test
131+
@Ignore("junit-team/junit4/issues/1720, validation uses actual object value, not just field type")
129132
public void rejectClassRuleIsAnArbitraryObject() throws Exception {
130133
TestClass target = new TestClass(TestWithClassRuleIsAnArbitraryObject.class);
131134
CLASS_RULE_VALIDATOR.validate(target, errors);
@@ -212,6 +215,7 @@ public Statement apply(Statement base, FrameworkMethod method,
212215
}
213216

214217
@Test
218+
@Ignore("junit-team/junit4/issues/1720, validation uses actual object value, not just field type")
215219
public void rejectArbitraryObjectWithRuleAnnotation() throws Exception {
216220
TestClass target = new TestClass(TestWithArbitraryObjectWithRuleAnnotation.class);
217221
RULE_VALIDATOR.validate(target, errors);

0 commit comments

Comments
 (0)