### Question:
OutputStreamDescriptionFactory { @SuppressWarnings("unchecked") public List<OutputStreamDescription> createOutputStreamDescriptions(Class<?> componentClass) { List<OutputStreamDescription> descriptions = new ArrayList<>(); Set<Field> fields = getAllFields(componentClass, withAnnotation(OutputStream.class)); for (Field field : fields) { if (field.getType() != Stream.class) { throw new IllegalArgumentException(OutputStream.class + " can only be applied to " + Stream.class); } OutputStream annotation = field.getAnnotation(OutputStream.class); OutputStreamDescription description = createOutputStreamDescription(componentClass, annotation); descriptions.add(description); } return descriptions; }  @SuppressWarnings("unchecked") List<OutputStreamDescription> createOutputStreamDescriptions(Class<?> componentClass);  }### Answer:
@Test public void should_retrieve_output_stream_descriptions() { @Documentation(name = "Test component") class TestComponent implements Component { @InputStream(name = "in") public Stream in; @ListMapper(stream = "in") public ListedFeaturesMapper inMapper; @OutputStream(from = "in", name = "out1") private Stream out1; @NameMapper(stream = "out1", expectedFeatures = {}) public NamedFeaturesMapper out1Mapper; @OutputStream(from = "", name = "out2") private Stream out2; @NameMapper(stream = "out2", expectedFeatures = {}) public NamedFeaturesMapper out2Mapper; @Override public void init() { } } List<FeatureDescription> newFeatures = new ArrayList<>(); when(featureDescriptorFactory.createDescriptions(isA(NameMapper.class))).thenReturn(newFeatures); List<OutputStreamDescription> actualDescriptions = factory.createOutputStreamDescriptions(TestComponent.class); assertThat(actualDescriptions).hasSize(2); assertThat(actualDescriptions).containsOnly( new OutputStreamDescription("out1", "in", NAMED, newFeatures), new OutputStreamDescription("out2", "", NAMED, newFeatures) ); }
@Test public void should_retrieve_user_selection_output_stream_descriptions() { @Documentation(name = "Test component") class TestComponent implements Component { @OutputStream(from = "in", name = "out1") private Stream out1; @ListMapper(stream = "out1") public ListedFeaturesMapper out1Mapper; @OutputStream(name = "out2") private Stream out2; @ListMapper(stream = "out2") public ListedFeaturesMapper out2Mapper; @Override public void init() { } } List<OutputStreamDescription> actualDescriptions = factory.createOutputStreamDescriptions(TestComponent.class); assertThat(actualDescriptions).containsOnly( new OutputStreamDescription("out1", "in", LISTED, new ArrayList<FeatureDescription>()), new OutputStreamDescription("out2", "", LISTED, new ArrayList<FeatureDescription>()) ); }
@Test(expected = IllegalArgumentException.class) public void should_throw_illegal_argument_exception_when_output_stream_annotation_not_applied_on_stream() { @Documentation(name = "Test component") class TestComponent implements Component { @InputStream(name = "in") public Stream in; @OutputStream(from = "in", name = "out1") private Object out1; @NameMapper(stream = "out1", expectedFeatures = {}) public NamedFeaturesMapper out1Mapper; @Override public void init() { } } factory.createOutputStreamDescriptions(TestComponent.class); }