From 8d3ec50e875cc91b752017163abeb0da076b5acc Mon Sep 17 00:00:00 2001 From: Marten Deinum Date: Mon, 14 Mar 2016 15:54:50 +0100 Subject: [PATCH] Support proxied objects in ReflectionTestUtils This commit adds support for unwrapping proxies in the setField() and getField() methods in ReflectionTestUtils. Instead of always accessing fields directly on the supplied targetObject (which may be a proxy), AopTestUtils is now used to obtain the potential ultimateTargetObject which is then used for accessing fields. Issue: SPR-14050 --- .../test/util/ReflectionTestUtils.java | 12 ++++--- .../test/util/ReflectionTestUtilsTests.java | 34 +++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java b/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java index f40227fb8c..65fe04fb84 100644 --- a/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java @@ -159,8 +159,10 @@ public class ReflectionTestUtils { Assert.isTrue(targetObject != null || targetClass != null, "Either targetObject or targetClass for the field must be specified"); + Object ultimateTargetObject = AopTestUtils.getUltimateTargetObject(targetObject); + if (targetClass == null) { - targetClass = targetObject.getClass(); + targetClass = ultimateTargetObject.getClass(); } Field field = ReflectionUtils.findField(targetClass, name, type); @@ -176,7 +178,7 @@ public class ReflectionTestUtils { targetObject, targetClass, value)); } ReflectionUtils.makeAccessible(field); - ReflectionUtils.setField(field, targetObject, value); + ReflectionUtils.setField(field, ultimateTargetObject, value); } /** @@ -234,8 +236,10 @@ public class ReflectionTestUtils { Assert.isTrue(targetObject != null || targetClass != null, "Either targetObject or targetClass for the field must be specified"); + Object ultimateTargetObject = AopTestUtils.getUltimateTargetObject(targetObject); + if (targetClass == null) { - targetClass = targetObject.getClass(); + targetClass = ultimateTargetObject.getClass(); } Field field = ReflectionUtils.findField(targetClass, name); @@ -250,7 +254,7 @@ public class ReflectionTestUtils { targetObject, targetClass)); } ReflectionUtils.makeAccessible(field); - return ReflectionUtils.getField(field, targetObject); + return ReflectionUtils.getField(field, ultimateTargetObject); } /** diff --git a/spring-test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java b/spring-test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java index fa692ed9b1..572eea0169 100644 --- a/spring-test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java @@ -22,6 +22,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.springframework.aop.framework.ProxyCreatorSupport; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.AopUtils; import org.springframework.test.util.subpackage.Component; import org.springframework.test.util.subpackage.LegacyEntity; import org.springframework.test.util.subpackage.Person; @@ -359,4 +362,35 @@ public class ReflectionTestUtilsTests { invokeMethod(component, "configure", new Integer(42), "enigma", "baz", "quux"); } + @Test + public void setAndGetFieldOnProxiedInstance() throws Exception { + ProxyFactory pf = new ProxyFactory(this.person); + pf.setProxyTargetClass(true); + + Person proxyPerson = (Person) pf.getProxy(); + + setField(proxyPerson, "id", new Long(99), long.class); + setField(proxyPerson, "name", "Tom"); + setField(proxyPerson, "age", new Integer(42)); + setField(proxyPerson, "eyeColor", "blue", String.class); + setField(proxyPerson, "likesPets", Boolean.TRUE); + setField(proxyPerson, "favoriteNumber", PI, Number.class); + + assertEquals("ID (private field in a superclass)", 99, person.getId()); + assertEquals("name (protected field)", "Tom", person.getName()); + assertEquals("age (private field)", 42, person.getAge()); + assertEquals("eye color (package private field)", "blue", person.getEyeColor()); + assertEquals("'likes pets' flag (package private boolean field)", true, person.likesPets()); + assertEquals("'favorite number' (package field)", PI, person.getFavoriteNumber()); + + assertEquals(new Long(99), getField(proxyPerson, "id")); + assertEquals("Tom", getField(proxyPerson, "name")); + assertEquals(new Integer(42), getField(proxyPerson, "age")); + assertEquals("blue", getField(proxyPerson, "eyeColor")); + assertEquals(Boolean.TRUE, getField(proxyPerson, "likesPets")); + assertEquals(PI, getField(proxyPerson, "favoriteNumber")); + + + } + }