使用Mockito / PowerMockito伪造方法参数

时间:2016-04-16 17:11:47

标签: java unit-testing apache-poi mockito powermockito

public class FakeExcelSheet implements Sheet
{
     private final Map<Integer, FakeExcelRow> fakeSheet = new HashMap<Integer, FakeExcelRow>();

     @Override
     public Row createRow(int rowNum)
     {
          Row row = new FakeExcelRow(rowNum, fakeSheet);
          fakeSheet.put(rowNum, (FakeExcelRow)row);
          return row;
     }

     @Override
     public Row getRow(int rowNum)
     {
          if (fakeSheet.get(rowNum) != null)
          {
               return fakeSheet.get(rowNum);
          }
          else
          {
               return createRow(rowNum);
          }

     }

     /**Other unimplemented methods of Apache POI class Sheet**/ 
}

public class FakeExcelRow implements Row
{
    private int rowNum;
    private Map<Integer, FakeExcelRow> sheet;
    private List<Object> cellList = new LinkedList<Object>();

    public FakeExcelRow(int rowNum , Map<Integer,FakeExcelRow> sheet)
    {
          this.rowNum = rowNum;
          this.sheet = sheet;
    }

    @Override
    public Cell createCell(int colNum)
    {
         return new FakeExcelCell(colNum, rowNum, sheet);
    }

    /**Other unimplemented methods of Apache POI class Row**/
}

public class FakeExcelCell implements Cell
{
      private int colNum;
      private int rowNum;
      private Map<Integer, FakeExcelRow> sheet;

      public FakeExcelCell(int colNum, int rowNum, Map<Integer, FakeExcelRow> sheet)
      {
          this.colNum = colNum;
          this.rowNum = rowNum;
          this.sheet = sheet;
      }

      public void setCellValue(String value)
      {
           if(sheet != null)
           {
                FakeExcelRow fakeExcelRow = sheet.get(rowNum);
                List<Object> cellList = fakeExcelRow.getCellList();
                cellList.add(value);
           }
      }

      /**Other unimplemented methods of Apache POI class Cell**/
}

我必须测试我的类服务,它使用类ExcelWriter的受保护方法writeToCell,如下所示:

public class ServiceImpl
{
     ........
     .
     .
     private ExcelWriter excelWriter;
     private Sheet sheet;
     private void handleRequest()
     {

           while("Till there are more rows")
           {
           excelWriter.writeDetailsForCategory(List<String> listOfItems)
           }
     }
 }

ExcelWriter类的设计如下:

public class ExcelWriter()
{
     protected Sheet sheet;
     public void writeDetailsForCategory(List<String> listOfItems)
     {
           for(String item : listOfItems)
           {
                 writeToCell(rowNum, columnNum, value, sheet);
                 columnNum++;
           }
     }
}

writeToCell()方法设计有受保护的访问修饰符:

protected void writeCell(int rowNum, int colNum, String value, Sheet sheet)
{

    if (value == null)
    {
        return;
    }

    Row row = sheet.getRow(rowNum);

    if (row == null)
    {
        row = sheet.createRow(rowNum);
    }

    Cell cell = row.createCell(colNum);
    cell.setCellValue(value);

}

我必须对使用ExcelWriter&#39; handleRequest的{​​{1}}类ServiceImpl方法进行单元测试,该方法使用受保护的方法writeDetailsForCategory。我在writeToCell方法中传递了FakeExcelSheet。我将在此之后断言writeToCell的值。我应该如何在Map <Object, FakeExcelRow> protected方法中传递fakeExcelSheet参数?我的限制是我只能使用Mockito或PowerMockito。

1 个答案:

答案 0 :(得分:1)

从我的other answer继续,您可以将ExcelWriter替换为StringGridWriter,该StringGrid会写入给定的public final class StringGridWriter() { private final StringGrid grid; public StringGridWriter(StringGrid grid) { this.grid = grid; } public void writeDetailsForCategory(List<String> listOfItems) { for(String item : listOfItems) { grid.writeToCell(rowNum, columnNum, value); columnNum++; } } } 。它不知道或不关心它是否优秀。

public class ServiceImpl {
     ........
     .
     .
     private final StringGridWriter gridWriter;

     public ServiceImpl(StringGridWriter gridWriter) {
         this.gridWriter = gridWriter;
     }

     private void handleRequest() {    
           while("Till there are more rows"){
             gridWriter.writeDetailsForCategory(List<String> listOfItems)
           }
     }
 }

服务中的用法:

Sheet theApacheSheet = ...;

StringGrid grid = new ApacheSheetStringGrid(theApacheSheet);

StringGridWriter writer = new StringGridWriter(grid);

ServiceImpl service = new ServiceImpl(writer);

这就是你如何分配使用它:

ApacheSheetStringGrid

根据我的其他答案ServiceImpl。所以现在,即使<link rel="stylesheet" href="//rawgit.com/angular/bower-material/master/angular-material.css"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js"></script> <script src="//rawgit.com/angular/bower-material/master/angular-material.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-animate.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-aria.min.js"></script> </script> 也不知道这是使用excel。在实践中注入依赖关系是Dependency Inversion Principle

看看我如何迅速摆脱复杂的excel界面,把它归结为一个抽象,一个功能的子集,这只是我的客户想要的接口(Interface Segregation Principle),这使得它很容易测试,并且易于替换其他实现。通过不抽象,您将代码紧密地耦合到apache excel实现。