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 d46a7ca37f..865c9e3a5c 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,10 +104,18 @@ public class ReflectionTestUtils { public static void setField(Object target, String name, Object value, Class type) { Assert.notNull(target, "Target object must not be null"); Field field = ReflectionUtils.findField(target.getClass(), name, type); - Assert.notNull(field, "Could not find field [" + name + "] on target [" + target + "]"); + + // SPR-9571: inline Assert.notNull() in order to avoid accidentally invoking + // toString() on a non-null target. + if (field == null) { + throw new IllegalArgumentException(String.format("Could not find field [%s] of type [%s] on target [%s]", + name, type, target)); + } if (logger.isDebugEnabled()) { - logger.debug("Setting field [" + name + "] on target [" + target + "]"); + logger.debug(String.format("Setting field [%s] of type [%s] on target [%s] to value [%s]", name, type, + target, + value)); } ReflectionUtils.makeAccessible(field); ReflectionUtils.setField(field, target, value); 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 f4d25452ad..0634161c3b 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,15 @@ package org.springframework.test.util; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.springframework.test.util.ReflectionTestUtils.getField; -import static org.springframework.test.util.ReflectionTestUtils.invokeGetterMethod; -import static org.springframework.test.util.ReflectionTestUtils.invokeMethod; -import static org.springframework.test.util.ReflectionTestUtils.invokeSetterMethod; -import static org.springframework.test.util.ReflectionTestUtils.setField; +import static org.junit.Assert.*; +import static org.springframework.test.util.ReflectionTestUtils.*; import org.junit.Ignore; import org.junit.Test; + import org.springframework.test.AssertThrows; import org.springframework.test.util.subpackage.Component; +import org.springframework.test.util.subpackage.LegacyEntity; import org.springframework.test.util.subpackage.Person; /** @@ -111,6 +108,17 @@ public class ReflectionTestUtilsTests { }.runTest(); } + /** + * Verifies behavior requested in SPR-9571. + */ + @Test + public void setFieldOnLegacyEntityWithSideEffectsInToString() { + String testCollaborator = "test collaborator"; + LegacyEntity entity = new LegacyEntity(); + setField(entity, "collaborator", testCollaborator, Object.class); + assertTrue(entity.toString().contains(testCollaborator)); + } + @Test public void invokeSetterAndMethods() throws Exception { diff --git a/spring-test/src/test/java/org/springframework/test/util/subpackage/LegacyEntity.java b/spring-test/src/test/java/org/springframework/test/util/subpackage/LegacyEntity.java new file mode 100644 index 0000000000..a31f450d15 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/util/subpackage/LegacyEntity.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.util.subpackage; + +import org.springframework.core.style.ToStringCreator; + +/** + * A legacy entity whose {@link #toString()} method has side effects; + * intended for use in unit tests. + * + * @author Sam Brannen + * @since 3.2 + */ +public class LegacyEntity { + + private Object collaborator = new Object() { + + public String toString() { + throw new RuntimeException( + "Invoking toString() on the default collaborator causes an undesirable side effect"); + }; + }; + + + public String toString() { + return new ToStringCreator(this)// + .append("collaborator", this.collaborator)// + .toString(); + } + +}