org.mockito.internal.util.reflection.BeanPropertySetter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mockito-core Show documentation
Show all versions of mockito-core Show documentation
Mockito mock objects library core API and implementation
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.util.reflection;
import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.plugins.MemberAccessor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
/**
* This utility class will call the setter of the property to inject a new value.
*/
public class BeanPropertySetter {
private static final String SET_PREFIX = "set";
private final Object target;
private final boolean reportNoSetterFound;
private final Field field;
/**
* New BeanPropertySetter
* @param target The target on which the setter must be invoked
* @param propertyField The field that should be accessed with the setter
* @param reportNoSetterFound Allow the set method to raise an Exception if the setter cannot be found
*/
public BeanPropertySetter(
final Object target, final Field propertyField, boolean reportNoSetterFound) {
this.field = propertyField;
this.target = target;
this.reportNoSetterFound = reportNoSetterFound;
}
/**
* New BeanPropertySetter that don't report failure
* @param target The target on which the setter must be invoked
* @param propertyField The propertyField that must be accessed through a setter
*/
public BeanPropertySetter(final Object target, final Field propertyField) {
this(target, propertyField, false);
}
/**
* Set the value to the property represented by this {@link BeanPropertySetter}
* @param value the new value to pass to the property setter
* @return true
if the value has been injected, false
otherwise
* @throws RuntimeException Can be thrown if the setter threw an exception, if the setter is not accessible
* or, if reportNoSetterFound
and setter could not be found.
*/
public boolean set(final Object value) {
MemberAccessor accessor = Plugins.getMemberAccessor();
Method writeMethod = null;
try {
writeMethod = target.getClass().getMethod(setterName(field.getName()), field.getType());
accessor.invoke(writeMethod, target, value);
return true;
} catch (InvocationTargetException e) {
throw new RuntimeException(
"Setter '"
+ writeMethod
+ "' of '"
+ target
+ "' with value '"
+ value
+ "' threw exception : '"
+ e.getTargetException()
+ "'",
e);
} catch (IllegalAccessException e) {
throw new RuntimeException(
"Access not authorized on field '"
+ field
+ "' of object '"
+ target
+ "' with value: '"
+ value
+ "'",
e);
} catch (NoSuchMethodException e) {
reportNoSetterFound();
}
reportNoSetterFound();
return false;
}
/**
* Retrieve the setter name from the field name.
*
* Implementation is based on the code of {@link java.beans.Introspector}.
*
* @param fieldName the Field name
* @return Setter name.
*/
private String setterName(String fieldName) {
return new StringBuilder(SET_PREFIX)
.append(fieldName.substring(0, 1).toUpperCase(Locale.ENGLISH))
.append(fieldName, 1, fieldName.length())
.toString();
}
private void reportNoSetterFound() {
if (reportNoSetterFound) {
throw new RuntimeException(
"Problems setting value on object: ["
+ target
+ "] for property : ["
+ field.getName()
+ "], setter not found");
}
}
}