In my Java (Spring Boot) app, I am trying to test the following method using JUnit5 and Mockito:
public abstract class CsvService<T extends CsvBean> {
public List<T> readFromCsv(Class<T> type, CsvToBeanFilter filter) {
List<T> data = new ArrayList<>();
try {
Resource resource = new ClassPathResource("data/" getFileName());
Reader reader = new FileReader(resource.getFile());
ColumnPositionMappingStrategy<T> strategy =
new ColumnPositionMappingStrategy<>();
strategy.setType(type);
strategy.setColumnMapping(getColumns());
CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(reader)
.withFilter(filter)
.build();
data = getData(csvToBean);
reader.close();
} catch (IOException ex) {
log.error(FILE_READ_ERROR, ex);
ex.printStackTrace();
}
return data;
}
protected abstract String getFileName();
protected abstract String[] getColumns();
protected abstract List<T> getData(CsvToBean<T> csvToBean);
}
I already wrote Unit Test for the method implementations of the abstract methods (getData()
, etc.), but I also want to write Unit Test for this readFromCsv()
method.
@Service
public class AirportService extends CsvService<Airport> {
// code omitted
@Override
protected List<Airport> getData(CsvToBean<Airport> csvToBean) {
List<Airport> airports = new ArrayList<>();
for (Airport bean : csvToBean) {
Airport airport = new Airport(
bean.getId()
);
airports.add(airport);
}
return airports;
}
}
Here is my Unit Test:
@ExtendWith(MockitoExtension.class)
class CsvServiceTest {
private CsvService service;
@Mock
private AirportService airportService;
@Mock
private CsvToBean<Airport> csvToBean;
@Mock
private CsvToBeanFilter filter;
@BeforeEach
void setup() {
service = new AirportService();
}
@Test
void test() {
csvToBean.setFilter(filter);
Airport airport = new Airport(101, "DK");
when(filter.allowLine((String[]) any())).thenReturn(true);
when(csvToBean.iterator())
.thenReturn(new ArrayIterator<>(new Airport[]{airport}));
List<Airport> result = service.readFromCsv(Airport.class, filter);
// assertions
}
}
But the test is always read the CSV file as it retrieved via getFileName()
method (the file in the project). But I want to mock it and read the provided airport data via stub. So, how can I make this unit test properly testing this CSV reader method?
CodePudding user response:
Either (1) create a Spy
instead of the AirportService
and mock the getFileName()
method:
service = Mockito.spy(new AirportService());
and then mock the desired method:
Mockito.doReturn((/* your value */)).when(service).getFileName();
or (2) create yet another class, this time extending the AirportService
; there you can implement the getFileName
so it returns your mock file name.