7

When using opencsv with annotation and StatefulBeanToCsv, headers are not written when bean list is empty. I would assume this test successful but it's not.

private class bean1 {
    @CsvBindByName(column = "column1")
    private String col1;

    public String getCol1() {
        return col1;
    }

    public void setCol1(String col1) {
        this.col1 = col1;
    }
}

@Test
public void testOpenCsvEmptyBeanList() throws CsvException {
    StringWriter sw = new StringWriter();
    
    StatefulBeanToCsv<bean1> sbc = new StatefulBeanToCsvBuilder<bean1>(sw)
            .withLineEnd(CSVWriter.DEFAULT_LINE_END)
            .build();
    
    // empty bean list
    sbc.write(new ArrayList<>());
    
    assertEquals("column1" + CSVWriter.DEFAULT_LINE_END, sw.toString());
}

Any idea to make this test works ?

Jey350
  • 103
  • 3

2 Answers2

0

I really doubt for that to be possible. Looking at the code of StatefulBeanToCsv, nothing is written if the list is empty.

public void write(List<T> beans) throws CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
    if (CollectionUtils.isNotEmpty(beans)) {
        write(beans.iterator());
    }
}
nyg
  • 2,380
  • 3
  • 25
  • 40
0

If you don't mind an extra empty line after the header

We can

import static org.junit.jupiter.api.Assertions.assertEquals;
import com.opencsv.CSVWriter;
import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.opencsv.exceptions.CsvChainedException;
import com.opencsv.exceptions.CsvException;
import com.opencsv.exceptions.CsvFieldAssignmentException;
import org.junit.jupiter.api.Test;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

public class EmptyListButWriteHeader {

    @Test
    public void testOpenCsvEmptyBeanList() throws CsvException {
        StringWriter sw = new StringWriter();

        HeaderColumnNameMappingStrategy<Bean1> mappingStrategy = new HeaderColumnNameMappingStrategy<>() {
            @Override
            public String[] transmuteBean(Bean1 bean) throws CsvFieldAssignmentException, CsvChainedException {
                // compare by reference to avoid other bean matches
                if (bean == Bean1.EMPTY_LINE_INSTANCE) {
                    return new String[0];
                }
                return super.transmuteBean(bean);
            }
        };
        mappingStrategy.setType(Bean1.class);
        StatefulBeanToCsv<Bean1> sbc = new StatefulBeanToCsvBuilder<Bean1>(sw)
                .withLineEnd(CSVWriter.DEFAULT_LINE_END)
                .withApplyQuotesToAll(false)
                .withMappingStrategy(mappingStrategy)
                .build();

        List<Bean1> bean1s = new ArrayList<>();
        if (bean1s.isEmpty()) {
            // add empty line bean when list is empty
            bean1s.add(Bean1.EMPTY_LINE_INSTANCE);
        }
        sbc.write(bean1s);

        assertEquals("COLUMN1" + CSVWriter.DEFAULT_LINE_END.repeat(2), sw.toString());
    }
}

class Bean1 {
    public static final Bean1 EMPTY_LINE_INSTANCE = new Bean1();
    @CsvBindByName(column = "column1")
    private String col1;

    public String getCol1() {
        return col1;
    }

    public void setCol1(String col1) {
        this.col1 = col1;
    }
}
samabcde
  • 6,988
  • 2
  • 25
  • 41