【问题标题】:Faking Method parameters using Mockito/PowerMockito使用 Mockito/PowerMockito 伪造方法参数
【发布时间】:2016-04-16 17:11:46
【问题描述】:
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 的 writeDetailsForCategoryServiceImpl 类的 handleRequest 方法进行单元测试,该方法使用受保护的方法 writeToCell。我已经在writeToCell 方法中传递了FakeExcelSheet。在此之后我将断言Map &lt;Object, FakeExcelRow&gt; 的值。我应该如何在protectedwriteToCell方法中传入fakeExcelSheet参数?我的限制是我只能使用 Mockito 或 PowerMockito。

【问题讨论】:

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


    【解决方案1】:

    从我的other answer 开始,您可以将特定的ExcelWriter 替换为StringGridWriter,它会写入给定的StringGrid。它不知道也不关心它是 excel。

    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 也不知道这是在使用 excel。这种依赖注入实际上是Dependency Inversion Principle

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多