### Question:
PropertyDescriptionFactory { @SuppressWarnings("unchecked") public List<PropertyDescription> createPropertyDescriptions(Class<?> componentClass) { List<PropertyDescription> propertyDescriptions = new ArrayList<>(); Set<Field> propertyFields = getAllFields(componentClass, withAnnotation(Property.class)); for (Field propertyField : propertyFields) { Property property = propertyField.getAnnotation(Property.class); PropertyDescription propertyDescription = new PropertyDescription(property.name(), property.description(), property.mandatory(), fromType(propertyField.getType())); if (PropertyType.ENUM.equals(propertyDescription.getType())) { List<String> enumValues = retrieveEnumValues(propertyField); propertyDescription.setAcceptedValues(enumValues); } propertyDescriptions.add(propertyDescription); } return propertyDescriptions; }  @SuppressWarnings("unchecked") List<PropertyDescription> createPropertyDescriptions(Class<?> componentClass);  }### Answer:
@Test public void should_retrieve_single_property_description() { @Documentation(name = "Test component") class TestComponent implements Component { @Property(name = "expected property", description = "tested property", mandatory = false) public String expectedProperty; @Override public void init() { } } List<PropertyDescription> actualDescriptions = factory.createPropertyDescriptions(TestComponent.class); assertThat(actualDescriptions).hasSize(1); PropertyDescription actualPropertyDescription = actualDescriptions.get(0); assertThat(actualPropertyDescription).isEqualTo( new PropertyDescription("expected property", "tested property", false, STRING)); }
@Test public void should_retrieve_enum_description() { @Documentation(name = "Test component") class TestComponent implements Component { @Property(name = "enum") public TestEnum expectedProperty; @Override public void init() { } } List<PropertyDescription> actualDescriptions = factory.createPropertyDescriptions(TestComponent.class); assertThat(actualDescriptions).containsOnly(propertyDescription("enum", ENUM).accepted("VALUE1", "VALUE2", "VALUE3").build()); }
@Test(expected = IllegalArgumentException.class) public void should_throw_illegal_argument_exception_with_unsupported_property_description_type() { @Documentation(name = "Test component") class TestComponent implements Component { @Property(name = "object") public Object object; @Override public void init() { } } factory.createPropertyDescriptions(TestComponent.class); }
@Test(expected = IllegalArgumentException.class) public void should_throw_illegal_argument_exception_when_properties_have_same_names() { @Documentation(name = "Test component") class TestComponent implements Component { @Property(name = "same name") public String stringProperty; @Property(name = "same name") public int intProperty; @Override public void init() { } } factory.createPropertyDescriptions(TestComponent.class); }