问题
I'm using Apache POI methods for writing to excel sheets in java. I have to do unit-testing for the methods which I have written. I have used many methods of Apache POI. Should I stub all the methods of the different object classes of Apache POI?
Example: I have created wrapper methods for writing to cell which are using Apache POI methods.
protected void writeCell(int rowNum, int colNum, String value, Sheet sheet)
{
if(value == null)
{
return;
}
Row row = sheet.getRow(rowNum);
Cell cell = row.createCell(colNum);
cell.setCellValue();
}
}
Should I mock even the methods like getRow
of the Sheet.class
and createCell
of the Row class?
回答1:
Test for results, not implementation.
I.e. If I write a cell, can I now read that value back from that cell?
Also you showed us a protected
method, you should only need to test the public interface of your classes. If you can't see results though the public interface, your class is probably doing too much (Single Responsibility Principle).
However, the other considerations are ones of speed and fragility, because Apache POI is reading and writing to actual files, it will be a little harder to write these tests and they will be slower. OK for a few tests, but if the whole suite is reading and writing files then it's going to get slow, and the entire test suite should run in a matter of a few seconds ideally.
So I would create an interface that encapsulates an excel sheet and what you want to do with it, this might be:
public interface StringGrid {
String readCell(int rowNum, int colNum);
void writeCell(int rowNum, int colNum, String value);
}
Now I might do a quick implementation without automated tests, or just a few simple tests around Apache POI, but then the rest of my suite would test against a Fake implementation of the StringGrid
and I can get on creating lots of fast running tests around my code.
So these might look like:
The real implementation, used only in its tests and the live program.
public final class ApacheSheetStringGrid implements StringGrid {
private final Sheet theApacheSheet;
public ApacheSheetStringGrid(Sheet theApacheSheet) {
this.theApacheSheet = theApacheSheet;
}
public String readCell(int rowNum, int colNum){
...
}
public void writeCell(int rowNum, int colNum, String value) {
Row row = theApacheSheet.getRow(rowNum);
Cell cell = row.createCell(colNum);
cell.setCellValue();
}
}
The Fake (a working, fast, in-memory only implementation of StringGrid
), for all other testing:
public final class FakeStringGrid implements StringGrid {
private final Map<String, String> contents = new HashMap<String, String>();
private static String getKey(int rowNum, int colNum) {
return rowNum + ", " + colNum;
}
public String readCell(int rowNum, int colNum){
return contents.get(getKey(rowNum, colNum));
}
public void writeCell(int rowNum, int colNum, String value) {
contents.put(getKey(rowNum, colNum), value);
}
}
This has extra benefits, you can later swap out the live implementation for another, maybe using one of the other POI approaches or even google sheets implementation and you'll only need to add a few tests and a new implementation and won't need to modify any code (Open Closed Principle).
来源:https://stackoverflow.com/questions/36638554/unit-testing-of-jar-methods-in-java