Normally I do not bother testing setters and getters, they are usually too boring to expect any bugs lurking in there. I recently started working on a project that requires a test coverage of at least 75%, and I realized that to reach this percentage with classes that have relatively many setters/getters and only a little bit of other code, I wanted to test the setters and getters.
Also, these setters and getters may contains trivial but nasty bugs that should be tested. It has happened (some years ago) that I incorrectly implemented a setter this way:
public void setName(String name) {
name = name;
}
I know, it's a pretty stupid mistake and still quite easy to make.
I created an automatic testing helper that will go through all methods of a class and if it detects a setter, invokes it with an appropriate test value and checks it by invoking the corresponding getter (if it exists). The return value of the getter should be the same as the value passed to the setter.
public void invokeSettersAndGetters() {
Classextends Object> targetClass = testTarget.getClass();
Method[] methods = targetClass.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (method.getName().startsWith("set")) {
Class[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Object testValue = testValueFactory.createValue(parameterTypes[0]);
try {
method.invoke(testTarget, testValue);
if (testValue instanceof Boolean) {
invokeGetter(targetClass, testValue, "is" + method.getName().substring(3));
} else {
invokeGetter(targetClass, testValue, "get" + method.getName().substring(3));
}
} catch (IllegalAccessException e) {
Assert.fail("failed to access setter method: " + method.toString() + " - " + e.getMessage());
} catch (InvocationTargetException e) {
Assert.fail("failed to invoke setter method: " + method.toString() + " - " + e.getMessage());
}
}
}
}
}
This method will invoke the getter and check the return value:
private void invokeGetter(Class targetClass, Object expectedValue, String getterName) {
try {
Method getterMethod = targetClass.getMethod(getterName);
if (log.isDebugEnabled()) {
log.debug("invoke get method: " + getterMethod.toString());
}
Object retrievedValue = getterMethod.invoke(testTarget);
Class returnType = getterMethod.getReturnType();
if (returnType.isPrimitive()) {
Assert.assertEquals("return value of " + getterName + " incorrect", expectedValue, retrievedValue);
} else {
Assert.assertSame("return value of " + getterName + " incorrect", expectedValue, retrievedValue);
}
} catch (NoSuchMethodException ignore) {
// ignore if getter does not exist
if (log.isDebugEnabled()) {
log.debug("getter does not exist: " + getterName);
}
} catch (IllegalAccessException e) {
Assert.fail("failed to access getter method: " + getterName + " - " + e.getMessage());
} catch (InvocationTargetException e) {
Assert.fail("failed to invoke getter method: " + getterName + " - " + e.getMessage());
}
}















