需要使用 mockito 测试 apache poi excel



我写了一个类来根据传递的数据创建工作簿。我现在正在编写模拟测试来测试我的方法。我不允许使用powermock。以下是代码片段。

public class TalkDetailsToExcel extends AbstractXlsView {
    private static final ResourceBundle RESOURCE_BUNDLE = MessageResource.getResourceBundle();
    /**
     * Builds the {@link Workbook} containing {@link Talk} details and adds to the {@link Sheet}.
     *
     * @param model               the {@link Map} containing the {@link List} of {@link Talk}.
     * @param workbook            the Excel {@link Workbook} to which {@link Talk} needs to be added.
     * @param httpServletRequest  the {@link HttpServletRequest}
     * @param httpServletResponse the {@link HttpServletResponse}
     * @throws Exception          when adding talk details to workbook.
     */
    @Override
    protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest httpServletRequest,
                                      HttpServletResponse httpServletResponse) throws Exception {
        final String talkListName = "talkList";
        final String fileName = "Talk Details.xls";
        httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        List<Talk> talkList = (List<Talk>) model.get(talkListName);
        Sheet sheet = createAndReturnSheetFromWorkbook(workbook);
        addTalkDetailsToSheet(talkList, sheet);
    }
    /**
     * Creates data cells to the {@link Sheet}.
     *
     * @param talkList the {@link List} of {@link Talk} objects.
     * @param sheet    the {@link Sheet} to which {@link Talk} details need to add.
     */
    @VisibleForTesting
    void addTalkDetailsToSheet(List<Talk> talkList, Sheet sheet) {
        Verifier.verifyNotNull(talkList, RESOURCE_BUNDLE.getString(MessageResource.SHEET_NULL));
        Verifier.verifyNotEmpty(talkList, RESOURCE_BUNDLE.getString(MessageResource.WORKBOOK_NULL));
        Verifier.verifyNotNull(sheet, RESOURCE_BUNDLE.getString(MessageResource.WORKBOOK_NULL));
        int rowCount = 1;
        for (Talk talk : talkList) {
            Row talkRow = sheet.createRow(rowCount++);
            talkRow.createCell(0).setCellValue(talk.getConference().getName());
            talkRow.createCell(1).setCellValue(talk.getTitle());
            talkRow.createCell(2).setCellValue(talk.getSpeaker());
            talkRow.createCell(3).setCellValue(talk.getCernerId());
            talkRow.createCell(4).setCellValue(String.valueOf(talk.getDifficultyLevel()));
            talkRow.createCell(5).setCellValue(talk.getDateTimeStr());
        }
    }
    /**
     * Creates and returns an empty {@link Sheet} containing header {@link Row}.
     *
     * @param workbook       the {@link Workbook} for which {@link Sheet} needs to be created.
     * @return {@link Sheet} containing the header {@link Row}.
     */
    public Sheet createAndReturnSheetFromWorkbook(Workbook workbook) {
        Verifier.verifyNotNull(workbook, RESOURCE_BUNDLE.getString(MessageResource.WORKBOOK_NULL));
        final String sheetName = "Conference Details";
        final String conferenceName = "Conference";
        final String talkTitle = "Talk";
        final String speakerName = "Speaker";
        final String cernerIdOfSpeaker = "Cerner Id";
        final String difficultyLevel = "Difficulty";
        final String dateTimeOfTalk = "Date Time";
        Sheet sheet = workbook.createSheet(sheetName);
        Row header = sheet.createRow(0);
        header.createCell(0).setCellValue(conferenceName);
        header.createCell(1).setCellValue(talkTitle);
        header.createCell(2).setCellValue(speakerName);
        header.createCell(3).setCellValue(cernerIdOfSpeaker);
        header.createCell(4).setCellValue(difficultyLevel);
        header.createCell(5).setCellValue(dateTimeOfTalk);
        return sheet;
    }
}
以下是我到目前为止编写的

编写 junit 的代码片段,我无法使用 createRow 模拟行。问题是行始终为空,测试引发空指针异常。任何建议都非常感谢。

   /**
   * Tests {@link TalkDetailsToExcel#createAndReturnSheetFromWorkbook(Workbook)} returns a {@link
   * Sheet}
   */
  @Test
  public void testCreateAndReturnSheetFromWorkbookReturnsSheet() {
    Workbook mockWorkbook = mock(Workbook.class);
    Sheet mockSheet = mock(Sheet.class);
    Row mockRow = mock(Row.class);
    doReturn(mockSheet).when(mockWorkbook).createSheet();
    doReturn(mockRow).when(mockSheet.createRow(anyInt()));
    Sheet sheet = mockTalkDetailsToExcel.createAndReturnSheetFromWorkbook(mockWorkbook);
  }

使用您提供的代码,我在此行复制了一个 NPE......

talkRow.createCell(0).setCellValue(...)

。因为尽管指定了模拟Row,但并未指示该模拟在调用createCell时返回Cell

这可以被嘲笑如下:

when(mockSheet.createRow(anyInt())).thenReturn(mockRow);
when(mockRow.createCell(anyInt())).thenReturn(mockCell);

因此,可以将测试重写为:

Workbook mockWorkbook = mock(Workbook.class);
Sheet mockSheet = mock(Sheet.class);
Row mockRow = mock(Row.class);
Cell mockCell = mock(Cell.class);
when(mockWorkbook.createSheet("Conference Details")).thenReturn(mockSheet);
when(mockSheet.createRow(0)).thenReturn(mockRow);
when(mockSheet.createRow(anyInt())).thenReturn(mockRow);
when(mockRow.createCell(anyInt())).thenReturn(mockCell);
Sheet sheet = mockTalkDetailsToExcel.createAndReturnSheetFromWorkbook(mockWorkbook);

这解决了NPE。

相关内容

  • 没有找到相关文章

最新更新