3

I have following method:

@Component
public class WriteCsvToResponse {

    private static final Logger LOGGER = LoggerFactory.getLogger(WriteCsvToResponse.class);

    public void writeStatus(PrintWriter writer, Status status) {

        try {

            ColumnPositionMappingStrategy mapStrategy
                = new ColumnPositionMappingStrategy();

            mapStrategy.setType(Status.class);

            String[] columns = new String[]{"id", "storeId", "status"};
            mapStrategy.setColumnMapping(columns);

            StatefulBeanToCsv btcsv = new StatefulBeanToCsvBuilder(writer)
                .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
                .withMappingStrategy(mapStrategy)
                .withSeparator(',')
                .build();

            btcsv.write(status);

        } catch (CsvException ex) {

            LOGGER.error("Error mapping Bean to CSV", ex);
        }
    }

I have no idea how to test it properly using mockito.

Use it to wrap the object status into csv format. I used StringWriter to wrap the response in it. There are no more details left, but it seems I have to create some words to pass the validation :)

Loïc Le Doyen
  • 975
  • 7
  • 16
John
  • 93
  • 2
  • 12
  • I am not sure what exactly do you do with `PrintWriter`. For example if you as result call `writer.write(status)` (inside `StatefulBeanToCsvBuilder`), you can mock it and check if it this method call. – borino Sep 11 '18 at 11:41
  • a hearty read of this article would help you: http://www.vogella.com/tutorials/Mockito/article.html – juju Sep 11 '18 at 11:41
  • 1
    Please try to identify broadly your difficulty, explain that and provide a tittle more explicit than "How to test such method using Mockito?". – davidxxx Sep 11 '18 at 11:59

3 Answers3

12

You do not need mockito to test this method, only a java.io.StringWriter.

Here is how you can write the test for a nominal use:

@Test
void status_written_in_csv_format() {
    // Setup
    WriteCsvToResponse objectUnderTest = new WriteCsvToResponse ();
    StringWriter stringWriter = new StringWriter();
    PrintWriter printWriter = new PrintWriter(stringWriter);

    // Given
    Status status = ...

    // When
    objectUnderTest.writeStatus(printWriter, status);

    // Then
    String actualCsv = stringWriter.toString();
    assertThat(actualCsv.split("\n"))
       .as("Produced CSV")
       .containsExactly(
         "id,storeId,status",
         "42,142,OK");
}

This example assume some things about your Status object, but you have the general idea. For assertions, I use AssertJ, but you can do the same with JUnit5 built-in assertions.

Hope this helps !

Loïc Le Doyen
  • 975
  • 7
  • 16
1

With a bit of a refactoring, where the Builder is a Spring Bean injected into this component.

You can then mock that builder to return a mocked StatefulBeanToCsv, specifically the write method, where you write the conditions and assertions. If you encounter an error, you throw some unchecked exception, like IllegalStateException, if everything is alright, you don't throw anything

László Stahorszki
  • 1,102
  • 7
  • 23
1

you can write a test like this and change your input in write method:

    @Test
    public void test() {
        WriteCsvToResponse writeCsvToResponse = mock(WriteCsvToResponse.class);

        doAnswer(new Answer() {
            public Object answer(InvocationOnMock invocation) {
                Object[] args = invocation.getArguments();
                write((Status)args[1]);
                return null;
            }
        }).when(writeCsvToResponse).writeStatus(any(PrintWriter.class),any(Status.class));

        writeCsvToResponse.writeStatus(writer, status);
    }

    public void write(Status status) {
//      do anythings you like with status
    }
Danial Jalalnouri
  • 609
  • 1
  • 7
  • 18