RTU.setField() shouldn't call toString() on target

ReflectionTestUtils.setField() implicitly calls toString() on the target
object when arguments for a call to Assert.notNull() are built. This can
have undesirable side effects, for example if the toString() invocation
results in a thrown exception or access to an external system (e.g., a
database).

This commit addresses this issue by inlining the Assert.notNull() code,
thereby avoiding accidental invocation of toString() on a non-null
target.

Issue: SPR-9571
This commit is contained in:
Sam Brannen
2012-08-10 16:44:55 +02:00
parent 5710cf5ed2
commit df961a938e
3 changed files with 72 additions and 11 deletions

View File

@@ -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 <a href="https://jira.springsource.org/browse/SPR-9571">SPR-9571</a>.
*/
@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 {

View File

@@ -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 <em>legacy entity</em> 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();
}
}