如何在C#中模拟枚举器

时间:2015-04-11 18:15:19

标签: c# mocking office-interop

我在C#中使用Microsoft Office Automation模型。例如,在Excel中,Workbook对象具有一个名为Sheets的属性,其中包含一个可枚举的Worksheet集合。 我想要的是

interface IWorkbook { ISheets Worksheets { get; } ... }

然后是一个实现:

class WorkbookImpl {
    private Excel.Workbook _workbook;
    public WorkbookImpl(Excel.Workbook workbook)
    {
        _workbook = workbook;
    }
    public ISheets Worksheets {
        get
        {
             // What goes here? something like
             return _workbook.Worksheets; // but obviously the type is wrong
        }
    }
 ...

关键是我以后可以实现各种接口的模拟,以便对代码进行IoC单元测试。

你能否建议如何完成这项工作,或者我的方法是否完全错误。

1 个答案:

答案 0 :(得分:1)

您似乎在Office Automation模型和代码之间有效地构建了适配器层。所以,要适应你已经拥有的东西:

class WorkbookAdapter : IWorkbookAdapter
{
    private Excel.Workbook _workbook;

    public WorkbookAdapter(Excel.Workbook workbook)
    {
        _workbook = workbook;
    }

    public IEnumerable<ISheetAdapter> Worksheets
    {
        get
        {
            return this._workbook.Sheets
                .Select(sheet => new SheetAdapter(sheet))
                .Cast<ISheetAdapter>();
        }
    }
}

..其中SheetAdapter类似于:

class SheetAdapter : ISheetAdapter
{
    private Excel.Sheet _sheet;

    public SheetAdapter(Excel.Sheet sheet)
    {
        _sheet = sheet;
    }

    // Sheet properties, methods, etc.
}

如果有意义,您可以将SheetAdapters缓存在列表中,以避免每次调用Select getter时都进行CastWorksheets调用。

现在,当你进行模拟时,可以使用List<ISheetAdapter>或类似的东西支持你的模拟,并避免模拟en枚举器。模拟枚举器或集合类型通常是代码气味,并导致各种困难。最好使用实际的集合类型。