Skip to content

Commit

Permalink
Add className variants in ReflectionHintsPredicates
Browse files Browse the repository at this point in the history
This commit adds predicates variants that accept `String className`
instead of actual `Class<?>` when checking for fields and method hints.
This is useful when the type under test is not visible from the current
test class.

Closes gh-29143
  • Loading branch information
bclozel committed Sep 13, 2022
1 parent 198e17f commit 5f62d1d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,23 @@ public MethodHintPredicate onMethod(Class<?> type, String methodName) {
return new MethodHintPredicate(getMethod(type, methodName));
}

/**
* Return a predicate that checks whether a reflection hint is registered for the method that matches the given selector.
* This looks up a method on the given type with the expected name, if unique.
* By default, both introspection and invocation hints match.
* <p>The returned type exposes additional methods that refine the predicate behavior.
* @param className the name of the class holding the method
* @param methodName the method name
* @return the {@link RuntimeHints} predicate
* @throws ClassNotFoundException if the class cannot be resolved.
* @throws IllegalArgumentException if the method cannot be found or if multiple methods are found with the same name.
*/
public MethodHintPredicate onMethod(String className, String methodName) throws ClassNotFoundException {
Assert.notNull(className, "'className' should not be null");
Assert.hasText(methodName, "'methodName' should not be null");
return onMethod(Class.forName(className), methodName);
}

private Method getMethod(Class<?> type, String methodName) {
ReflectionUtils.MethodFilter selector = method -> methodName.equals(method.getName());
Set<Method> methods = MethodIntrospector.selectMethods(type, selector);
Expand Down Expand Up @@ -148,6 +165,23 @@ public FieldHintPredicate onField(Class<?> type, String fieldName) {
return new FieldHintPredicate(field);
}

/**
* Return a predicate that checks whether a reflection hint is registered for the field that matches the given selector.
* This looks up a field on the given type with the expected name, if present.
* By default, unsafe or write access are not considered.
* <p>The returned type exposes additional methods that refine the predicate behavior.
* @param className the name of the class holding the field
* @param fieldName the field name
* @return the {@link RuntimeHints} predicate
* @throws ClassNotFoundException if the class cannot be resolved.
* @throws IllegalArgumentException if a field cannot be found with the given name.
*/
public FieldHintPredicate onField(String className, String fieldName) throws ClassNotFoundException {
Assert.notNull(className, "'className' should not be null");
Assert.hasText(fieldName, "'fieldName' should not be empty");
return onField(Class.forName(className), fieldName);
}

/**
* Return a predicate that checks whether a reflection hint is registered for the given field.
* By default, unsafe or write access are not considered.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

/**
* Tests for {@link ReflectionHintsPredicates}
Expand Down Expand Up @@ -319,6 +320,12 @@ void methodIntrospectionMatchesMethodHint() {
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
}

@Test
void methodIntrospectionFailsForUnknownType() {
assertThatThrownBy(() -> reflection.onMethod("com.example.DoesNotExist", "publicMethod").introspect())
.isInstanceOf(ClassNotFoundException.class);
}

@Test
void methodIntrospectionMatchesIntrospectPublicMethods() {
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_PUBLIC_METHODS);
Expand Down Expand Up @@ -472,6 +479,12 @@ void shouldFailForMissingField() {
assertThatIllegalArgumentException().isThrownBy(() -> reflection.onField(SampleClass.class, "missingField"));
}

@Test
void shouldFailForUnknownClass() {
assertThatThrownBy(() -> reflection.onField("com.example.DoesNotExist", "missingField"))
.isInstanceOf(ClassNotFoundException.class);
}

@Test
void fieldReflectionMatchesFieldHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
Expand Down

0 comments on commit 5f62d1d

Please sign in to comment.