模拟OpenXML SDK电子表格文档

本文关键字:文档 电子表格 SDK OpenXML 模拟 | 更新日期: 2023-09-27 17:58:47

我想使用这里描述的过程:自动测试OpenXML SDK(这里也提到:单元测试一个通过OpenXML与microsoft word对话的应用程序)

然而,嘲笑这样的东西需要什么呢?我制作了以下界面:

public interface IExcelDocument
{
    Row GetRow(uint rowIndex, SheetData sheetData);
    SharedStringTablePart GetSharedStringTablePart(SpreadsheetDocument excelDoc);
    WorksheetPart GetWorksheetPart(SpreadsheetDocument excelDoc, string sheetName);
    Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart);
    Row InsertRow(WorksheetPart worksheetPart);
    int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart);
}

我想嘲讽会是这样的:

[TestMethod()]
public void Excel_GetWorkseetPartTest()
{
    Mock<IExcelDocument> mockExcelDocument = new Mock<IExcelDocument>();
    string sheetName = "sheet";
    var excelMock = mockExcelDocument.Object.GetWorksheetPart(MySpreadsheetDocument, sheetName);
    Assert.IsTrue(excelMock != null);
}

GetWorksheetPart方法,我想对其进行单元测试,并驻留在实现接口IExcelDocument的类中,它看起来像这样:

public WorksheetPart GetWorksheetPart(SpreadsheetDocument excelDoc, string sheetName)
{
    Sheet sheet = excelDoc.WorkbookPart.Workbook.Descendants<Sheet>()
        .SingleOrDefault(s => s.Name == sheetName);
    if (sheet == null)
    {
        throw new ArgumentException(
            String.Format("No sheet named {0} found in spreadsheet {1}",
                sheetName, _filePath), "sheetName");
    }
    return (WorksheetPart)excelDoc.WorkbookPart.GetPartById(sheet.Id);
}

我无法绕过MySpreadsheetDocument,因为我还需要实现SpreadsheetDocument.Open方法,并且不确定这是否合理。

以下是我如何调用GetWorksheetPart:

using (SpreadsheetDocument _excelDoc = SpreadsheetDocument.Open(_filePath, true))
{
    IExcelDocument excelDoc = new ExcelDocument();
    WorksheetPart worksheetPart = excelDoc.GetWorksheetPart(_excelDoc, sheetName);
}

模拟OpenXML SDK电子表格文档

您混淆了为单元测试抽象依赖项的概念。

给出一个类的例子

public class ExcelDocument {
    public WorksheetPart GetWorksheetPart(SpreadsheetDocument excelDoc, string sheetName)
    {
        Sheet sheet = excelDoc.WorkbookPart.Workbook.Descendants<Sheet>()
            .SingleOrDefault(s => s.Name == sheetName);
        if (sheet == null)
        {
            throw new ArgumentException(
                String.Format("No sheet named {0} found in spreadsheet {1}",
                    sheetName, _filePath), "sheetName");
        }
        return (WorksheetPart)excelDoc.WorkbookPart.GetPartById(sheet.Id);
    }
}

该方法依赖于外部组件SpreadsheetDocument

SpreadsheetDocument就是在这种情况下需要抽象的内容。

查看测试中的方法,该方法需要能够获得Sheet,因此抽象必须提供该功能。它还需要能够获得WorksheetPart

由此可以导出以下接口

public ISpreadsheetDocument {    
    Sheet GetSheet(string name);
    WorksheetPart GetPartById(string id);
}

这将测试中的方法更改为该

public WorksheetPart GetWorksheetPart(ISpreadsheetDocument excelDoc, string sheetName)
{
    Sheet sheet = excelDoc.GetSheet(sheetName);
    if (sheet == null)
    {
        throw new ArgumentException(
            String.Format("No sheet named {0} found in spreadsheet {1}",
                sheetName, _filePath), "sheetName");
    }
    return excelDoc.GetPartById(sheet.Id);
}

如果单元测试需要,现在可以模拟/fack excelDoc,然后生产实现将封装外部功能。

public class SpreadsheetDocumentWrapper : ISpreadsheetDocument {
    private SpreadsheetDocument excelDoc;
    public SpreadsheetDocumentWrapper(SpreadsheetDocument excelDoc) {
        this.excelDock = excelDock;
    }
    public Sheet GetSheet(string name) {
        return excelDoc.WorkbookPart.Workbook.Descendants<Sheet>()
            .SingleOrDefault(s => s.Name == sheetName);
    }
    public WorksheetPart GetPartById(string id) {
        return (WorksheetPart)excelDoc.WorkbookPart.GetPartById(id);
    }
}

因此,您需要做的是查看ExcelDocument类,识别其依赖关系,并将这些依赖关系抽象为可以模拟用于单元测试的服务。