### Question:
ReflectionUtils { public Method getSetterMethodForField(final Class<?> fieldClass, final String fieldName, final Class<?> fieldType) { final String cacheKey = "SetterMethod-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(SET.getPrefix() + capitalize(fieldName), fieldType); method.setAccessible(true); CACHE_MANAGER.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { throw new MissingMethodException(e.getMessage()); } }); }  Object invokeMethod(final Method method, final Object target, final Object... args); boolean isSetter(final Method method); boolean isGetter(final Method method); Object getFieldValue(final Object target, final Field field); @SuppressWarnings("unchecked") Object getFieldValue(final Object target, final String fieldName, final Class<?> fieldType); A getFieldAnnotation(final Field field, final Class<A> annotationClazz); A getParameterAnnotation(final Parameter parameter, final Class<A> annotationClazz, final String declaringClassName); Field getDeclaredField(final String fieldName, final Class<?> targetClass); Class<?> getDeclaredFieldType(final String fieldName, final Class<?> clazz); void setFieldValue(final Object target, final String fieldName, final Object fieldValue); void setFieldValue(final Object target, final Field field, final Object fieldValue); Method getSetterMethodForField(final Class<?> fieldClass, final String fieldName, final Class<?> fieldType); Class<?> getGenericFieldType(final Field field); MapType getMapGenericType(final Type fieldType, final String declaringClass, final String fieldName); Class<?> getArgumentTypeClass(final Object argument, final String declaringClass, final String fieldName, final boolean getNestedGenericClass); Class<?> getArrayType(final Field arrayField);  }### Answer:
@Test public void testInvokeMethodWorksProperly() throws Exception { MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) .invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); assertThat(mutableToFoo).hasFieldOrPropertyWithValue(ID_FIELD_NAME, ONE); }
@Test public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong() { MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, LIST_FIELD_NAME, List.class); ThrowingCallable actual = () -> getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) .invoke(underTest, idSetterMethod, mutableToFoo, new Object[]{ONE}); assertThatThrownBy(actual).hasCauseInstanceOf(IllegalArgumentException.class); }
@Test public void testGetSetterMethodForFieldWorksProperly() { final Method actual = underTest.getSetterMethodForField(MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, EXPECTED_SETTER_METHOD_NAME); }
@Test(expectedExceptions = MissingMethodException.class) public void testGetSetterMethodForFieldThrowsExceptionIfTheMethodDoesNotExists() { underTest.getSetterMethodForField(MutableToFoo.class, NOT_EXISTING_FIELD_NAME, BigInteger.class); }