How to write unit test for class that writes data into word document with apache-poi java?

只愿长相守 提交于 2019-12-24 11:18:29

问题


I created a word-document with apache-poi (poi-ooxml version 3.15) and now I want to write unit tests for my classes. What is the best way to do that? We're using mockito(2.15.0) in our project.

This is one of the classes I'm trying to write test for:

@Component
public class ProffesionalSumaryService {


    public  void populateDocumentWithProfileSkills(XWPFDocument document, ExportProfileDTO profileData){

        XWPFTable antet = document.createTable();

antet.getCTTbl().getTblPr().getTblBorders().getBottom().setColor(COLOR_OF_TABLE_BORDERS);
        antet.getCTTbl().getTblPr().getTblBorders().getRight().setColor(COLOR_OF_TABLE_BORDERS);
        antet.getCTTbl().getTblPr().getTblBorders().getLeft().setColor(COLOR_OF_TABLE_ANTET_BACKGROUND);
        antet.getCTTbl().getTblPr().getTblBorders().getTop().setColor(COLOR_OF_TABLE_ANTET_BACKGROUND);

        CTTblWidth ctTblWidth = antet.getCTTbl().getTblPr().getTblW();
        ctTblWidth.setType(STTblWidth.PCT);
        ctTblWidth.setW(BigInteger.valueOf(6*TWIPS_PER_INCH));

        XWPFTableRow antetRow = antet.getRow(0);
        antetRow.getCell(0).removeParagraph(0);

        XWPFParagraph professionalSkills = antetRow.getCell(0).addParagraph();
        setStyles(professionalSkills.createRun() , FONT_CALIBRI ,SUBTITLE_FONT_SIZE , COLOR_FORTECH , "Professional Summary" , true, false);
        antetRow.getCell(0).setColor(COLOR_OF_TABLE_ANTET_BACKGROUND);

        XWPFParagraph paragraphSkills = document.createParagraph();
        XWPFTable skillsTable = document.createTable();

        skillsTable.getCTTbl().getTblPr().getTblBorders().getBottom().setColor(COLOR_OF_TABLE_BORDERS);
        skillsTable.getCTTbl().getTblPr().getTblBorders().getTop().setColor(COLOR_OF_TABLE_BORDERS);
        skillsTable.getCTTbl().getTblPr().getTblBorders().getLeft().setColor(COLOR_OF_TABLE_BORDERS);
        skillsTable.getCTTbl().getTblPr().getTblBorders().getRight().setColor(COLOR_OF_TABLE_BORDERS);
        skillsTable.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(COLUMN_WIDTH_SMALL));
        skillsTable.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(COLUMN_WIDTH_BIG));

        XWPFTableRow projectSkillsRow = skillsTable.getRow(0);

        XWPFParagraph _skills = projectSkillsRow.getCell(0).addParagraph();
        setStyles(_skills.createRun(), FONT_CALIBRI , FONT_SIZE_NORMAL, COLOR_FORTECH , "Skills" , false, false);

        projectSkillsRow.createCell();
        try{
            setSkillsBulletList(profileData.getSkillList(),document,projectSkillsRow);
        }catch(XmlException e){
            throw new RestExceptions.HeaderError();
        }
    }

    protected void setSkillsBulletList(List<SkillEntity> skillEntities, XWPFDocument document, XWPFTableRow projectSkillsRow) throws XmlException {
        String cTAbstractNumBulletXML =
                "<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"0\">"
                        + "<w:multiLevelType w:val=\"hybridMultilevel\"/>"
                        + "<w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:hint=\"default\"/></w:rPr></w:lvl>"
                        + "<w:lvl w:ilvl=\"1\" w:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"o\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\" w:hint=\"default\"/></w:rPr></w:lvl>"
                        + "<w:lvl w:ilvl=\"2\" w:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:hint=\"default\"/></w:rPr></w:lvl>"
                        + "</w:abstractNum>";

        XWPFRun run;
        CTNumbering cTNumbering = CTNumbering.Factory.parse(cTAbstractNumBulletXML);
        CTAbstractNum cTAbstractNum = cTNumbering.getAbstractNumArray(0);
        XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
        XWPFNumbering numbering = document.createNumbering();
        BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
        BigInteger numID = numbering.addNum(abstractNumID);
        projectSkillsRow.getCell(1).removeParagraph(0);
        if(skillEntities.size() != 0)
            for (SkillEntity skill : skillEntities) {
                XWPFParagraph item = projectSkillsRow.getCell(1).addParagraph();
                item.setNumID(numID);
                run = item.createRun();
                run.setText(skill.getSkillDescriptionEntity().getName() + " - " + SKILL_SCORES.values()[skill.getSkillScore()]);
            }
        else {
            XWPFParagraph item = projectSkillsRow.getCell(1).addParagraph();
            run = item.createRun();
            run.setText("No skills");
        }
    }

    private static void setStyles(XWPFRun run , String fontFamily , int fontSize , String colorRGB , String text , boolean bold , boolean addBreak) {
        run.setFontFamily(fontFamily);
        run.setFontSize(fontSize);
        run.setColor(colorRGB);
        run.setText(text);
        run.setBold(bold);
        if (addBreak) run.addBreak();
    }
}

And this is what I've found and tried until now:


@RunWith(MockitoJUnitRunner.class)
public class ProffesionalSumaryServiceTest  {

    private static final String UID = "uid";
    private static final int SKILL_SCORE = 3;


    @InjectMocks
    ProffesionalSumaryService proffesionalSumaryService;

    ExportProfileDTO exportProfileDTO;

    XWPFDocument mockDocument;
    XWPFTable mockTable;
    XWPFTableRow mockRow;
    XWPFParagraph mockParagraph;
    XWPFTableCell mockCell;
    XWPFRun mockRun;


    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        exportProfileDTO = makeExportProfileDto();
        mockDocument = mock(XWPFDocument.class);
        mockTable = mock(XWPFTable.class, Mockito.RETURNS_DEEP_STUBS);
        mockRow = mock(XWPFTableRow.class);
        mockParagraph = mock(XWPFParagraph.class);
        mockCell = mock(XWPFTableCell.class);
        mockRun = mock(XWPFRun.class);
    }



    @Test
    public void populateDocumentWithProfileSkills()  {

        CTBorder mockCTBorder = mock(CTBorder.class);
        CTTblWidth mockCTTblWidth = mock(CTTblWidth.class);

        when(mockDocument.createTable()).thenReturn(mockTable);

        when(mockTable.getCTTbl().getTblPr().getTblBorders().getBottom()).thenReturn(mockCTBorder);
        when(mockTable.getCTTbl().getTblPr().getTblBorders().getTop()).thenReturn(mockCTBorder);
        when(mockTable.getCTTbl().getTblPr().getTblBorders().getLeft()).thenReturn(mockCTBorder);
        when(mockTable.getCTTbl().getTblPr().getTblBorders().getRight()).thenReturn(mockCTBorder);

        doNothing().when(mockCTBorder).setColor(anyString());

        when(mockTable.getCTTbl().getTblPr().getTblW()).thenReturn(mockCTTblWidth);
        doNothing().when(mockCTTblWidth).setType(Mockito.any());
        doNothing().when(mockCTTblWidth).setW(Mockito.any());

        when(mockDocument.createParagraph()).thenReturn(mockParagraph);
        when(mockParagraph.createRun()).thenReturn(mockRun);
        when(mockTable.getRow(anyInt())).thenReturn(mockRow);
        when(mockRow.getCell(anyInt())).thenReturn(mockCell);
        when(mockCell.addParagraph()).thenReturn(mockParagraph);
        when(mockRow.createCell()).thenReturn(mockCell);

        proffesionalSumaryService.populateDocumentWithProfileSkills(mockDocument,exportProfileDTO);

    }


}

Do you know a better way of testing this class? I would appreciate any help.


回答1:


Your code is dominated by interactions with libraries. It contains only few computational parts. Moreover, the code creates a document that is meant to have a certain visual appearance.

It may make sense to extract the computational parts into separate methods and test these via unit-testing, but even that could be overkill here. The interactions, however, are better tested with integration-testing (that is, not with isolation using mocks). And, certainly, whether the result has the intended visual appearance needs to be analysed by looking at the resulting documents.



来源:https://stackoverflow.com/questions/57604594/how-to-write-unit-test-for-class-that-writes-data-into-word-document-with-apache

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!