Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate actual rule object instead of Field#type for @Rule #1721

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -230,6 +230,11 @@ public void validate(FrameworkMember<?> member, Class<? extends Annotation> anno
*/
private static final class FieldMustBeARule implements RuleValidator {
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
if (true) {
// Field type is not validated as field value can still implement the interface
// even in case field type does not.
return;
}
if (!isRuleType(member)) {
errors.add(new ValidationError(member, annotation,
"must implement MethodRule or TestRule."));
Expand Down Expand Up @@ -270,6 +275,11 @@ private static final class FieldMustBeATestRule implements RuleValidator {

public void validate(FrameworkMember<?> member,
Class<? extends Annotation> annotation, List<Throwable> errors) {
if (true) {
// Field type is not validated as field value can still implement the interface
// even in case field type does not.
return;
}
if (!isTestRule(member)) {
errors.add(new ValidationError(member, annotation,
"must implement TestRule."));
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/junit/runners/model/TestClass.java
Expand Up @@ -22,6 +22,8 @@
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.internal.MethodSorter;
import org.junit.rules.MethodRule;
import org.junit.rules.TestRule;

/**
* Wraps a class to be run, providing method validation and annotation searching
Expand Down Expand Up @@ -249,6 +251,10 @@ public <T> void collectAnnotatedFieldValues(Object test,
Object fieldValue = each.get(test);
if (valueClass.isInstance(fieldValue)) {
consumer.accept(each, valueClass.cast(fieldValue));
} else if (fieldValue != null && (valueClass == TestRule.class || valueClass == MethodRule.class)
&& !(fieldValue instanceof TestRule) && !(fieldValue instanceof MethodRule)) {
throw new IllegalArgumentException(each + " must implement MethodRule or TestRule." +
" Actual type is " + fieldValue.getClass());
}
} catch (IllegalAccessException e) {
throw new RuntimeException(
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/org/junit/rules/RuleMemberValidatorTest.java
Expand Up @@ -10,6 +10,7 @@
import java.util.List;

import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.model.FrameworkMethod;
Expand Down Expand Up @@ -76,6 +77,7 @@ static class NonPublicTestWithClassRule {
* <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
*/
@Test
@Ignore("junit-team/junit4/issues/1720, validation uses actual object value, not just field type")
public void rejectClassRuleThatIsImplementationOfMethodRule() {
TestClass target = new TestClass(TestWithClassRuleIsImplementationOfMethodRule.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
Expand Down Expand Up @@ -126,6 +128,7 @@ public Statement apply(Statement base, FrameworkMethod method, Object target) {
* <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
*/
@Test
@Ignore("junit-team/junit4/issues/1720, validation uses actual object value, not just field type")
public void rejectClassRuleIsAnArbitraryObject() throws Exception {
TestClass target = new TestClass(TestWithClassRuleIsAnArbitraryObject.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
Expand Down Expand Up @@ -212,6 +215,7 @@ public Statement apply(Statement base, FrameworkMethod method,
}

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