Support 4-arg Whitebox.setInternalState(target, field, value, Class)#1023
Merged
Conversation
The where-overload supplies the declaring class to look the field up on.
getDeclaredField does not walk the class hierarchy, so for an inherited
field child.getClass().getDeclaredField("name") throws NoSuchFieldException;
only Parent.class.getDeclaredField("name") resolves it.
Generate the field lookup with the 4th Class argument as the
getDeclaredField receiver instead of target.getClass(). Everything else
(setAccessible, field.set, throws Exception, Field import) is identical to
the existing 3-arg path. The Class-typed placeholder also accepts a
non-literal Class<?> variable as the 4th arg.
Collaborator
Author
|
#1021 is an ongoing refactoring with @steve-aom-elliott to break the recipe for expansion. This is the most pressing missing API. |
timtebeek
approved these changes
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Extends
PowerMockWhiteboxToJavaReflectionto also handle the 4-arg overloadWhitebox.setInternalState(target, "field", value, Class). The 3-arg form was alreadymigrated; this overload was left untouched.
Why
The 4th argument is the declaring class to look the field up on, and it matters because
getDeclaredFielddoes not walk the class hierarchy. For an inherited field,child.getClass().getDeclaredField("name")throwsNoSuchFieldException— onlyParent.class.getDeclaredField("name")resolves it. This overload is exactly what test codeuses to reach a field declared on a superclass.
The only semantic difference from the 3-arg path is the receiver of
getDeclaredField:setInternalState(child, "name", v)child.getClass()(runtime class only)setInternalState(child, "name", v, Parent.class)Parent.class(declaring superclass)Everything else —
setAccessible(true),field.set(target, value), thethrows Exception,the
java.lang.reflect.Fieldimport — is identical to the shipped 3-arg path. No cast, no boxing.Before → After
Notes
MethodMatcherforsetInternalState(Object, String, Object, Class); theString2ndparam disambiguates it from the
setInternalState(Object, Class, Object, Class)sibling overload.Classargument flows straight into a#{any(java.lang.Class)}placeholder, so anon-literal
Class<?>variable as the 4th arg works too (generateswhere.getDeclaredField(...)).displayName/descriptionare unchanged.Tests
Two new tests in
PowerMockWhiteboxToJavaReflectionTest:setInternalStateWithWhereClass— inherited field via a literalParent.class.setInternalStateWithWhereClassVariable— aClass<?>variable as the 4th arg../gradlew checkpasses (license, recipe CSV completeness/content validation, full test suite).