Here is some code
type Combiner interface {
Combine(files []io.Reader) (io.Reader, error)
}
type CsvCombiner struct {
hasHeader bool
}
func (c *csvCombiner) Combine(files []io.Reader) (io.Reader, error) {
combinedCSV := &bytes.Buffer{}
writer := csv.NewWriter(combinedCSV)
reader := csv.NewReader(file[0])
header, err := reader.Read()
if err != nil {
return nil, err
}
if err := writer.Write(header); err != nil {
return nil, err
}
// more code...
}
How would I write a test case for when writer.Write() fails? I'm finding it difficult to mock calls on structs that do not implement an interface (csv.Writer).
I've tried creating a separate interface:
type CSVWriter interface {
Write(record []string) error
Flush()
Error() error
}
and mocking it with testify/mock
type MockCSVWriter struct {
mock.Mock
}
func (m *MockCSVWriter) Write(record []string) error {
args := m.Called(record)
return args.Error(0)
}
func (m *MockCSVWriter) Flush() {
m.Called()
return
}
func (m *MockCSVWriter) Error() error {
args := m.Called()
return args.Error(0)
}
but this chunk of code doesn't mock the writer.Write() call
var mockCSVWriter MockCSVWriter
defer mockCSVWriter.AssertExpectations(t)
mockCSVWriter.On("Write", mock.Anything).Return(expectedError).Once()
Any suggestions would be greatly appreciated!
MockCSVWriter is not being sent to the CsvCombiner and new one is getting created always at
writer := csv.NewWriter(combinedCSV).Have a field in CsvCombiner to hold the CSVWriter, which can be replaced with the mocked one. type to be of interface that csv.Writer and MockCSVWriter both satisfy
Better approach will be to Mock interface
io.Writerthat is supplied tocsv.NewWriterinstead and pass this as a field inCsvCombinerstruct.Mock interface and usage
Also, write error can be thrown during csv Writer methods Write() and/or Flush() so check with
writer.Error()for getting the error