简体   繁体   English

如何使用apache-poi java为将数据写入Word文档的类编写单元测试?

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

I created a word-document with apache-poi (poi-ooxml version 3.15) and now I want to write unit tests for my classes. 我用apache-poi(poi-ooxml版本3.15)创建了一个word文档,现在我想为我的类编写单元测试。 What is the best way to do that? 最好的方法是什么? We're using mockito(2.15.0) in our project. 我们在项目中使用了模仿(2.15.0)。

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. 我将不胜感激任何帮助。

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. 并且,当然,需要通过查看生成的文档来分析结果是否具有预期的视觉外观。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM