我正在使用 Apache POI 方法在 Java 中写入 Excel 工作表。我必须对我编写的方法进行单元测试。我用过很多 Apache POI 的方法。我应该 stub Apache POI 不同对象类的所有方法吗?
示例:我创建了用于写入使用 Apache POI 方法的单元格的包装器方法。
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();
}
}
我是否应该甚至模拟 Sheet.class
的 getRow
和 Row 类的 createCell
方法?
最佳答案
测试结果,而不是实现。
即如果我写一个单元格,我现在可以从该单元格中读回该值吗?
您还向我们展示了一个protected
方法,您应该只需要测试类的公共(public)接口(interface)。如果您无法通过公共(public)接口(interface)看到结果,则您的类可能做得太多(单一职责原则)。
然而,其他考虑因素是速度和脆弱性,因为 Apache POI 正在读取和写入实际文件,编写这些测试会有点困难,而且它们会更慢。几个测试没问题,但如果整个套件都在读写文件,那么它会变慢,理想情况下,整个测试套件应该在几秒钟内运行。
所以我会创建一个接口(interface)来封装一个 excel 工作表以及你想用它做什么,这可能是:
public interface StringGrid {
String readCell(int rowNum, int colNum);
void writeCell(int rowNum, int colNum, String value);
}
现在我可能会在没有自动化测试的情况下快速实现,或者只是围绕 Apache POI 进行一些简单的测试,但我的套件的其余部分将针对 Fake 进行测试StringGrid
的实现,我可以围绕我的代码创建大量快速运行测试。
所以这些可能看起来像:
真正的实现,仅在其测试和实时程序中使用。
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();
}
}
Fake(StringGrid
的有效、快速、仅在内存中的实现),用于所有其他测试:
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);
}
}
这有额外的好处,您可以稍后将实时实现换成另一个,也许使用其他 POI 方法之一甚至谷歌表格实现,您只需要添加一些测试和一个新的实现就可以了不需要修改任何代码(开闭原则)。
关于java - Java中Jar方法的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36638554/