模拟OpenXML SDK SpreadsheetDocument

时间:2016-07-27 13:15:12

标签: c# unit-testing moq openxml-sdk

我想使用此处描述的流程:Automated Testing OpenXML SDK (也在这里触及:Unit testing an application that talks to microsoft word via OpenXML

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

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);
}

1 个答案:

答案 0 :(得分:2)

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

给出一个示例类

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类,识别它的依赖关系并将这些依赖关系抽象出来,你可以模拟单元测试的服务。