如何在 C# 中模拟枚举器

How to mock an enumerator in C#

我正在使用 C# 中的 Microsoft Office 自动化模型。例如,在 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 单元测试。

你能建议如何完成这项工作吗?还是我的方法完全错误。

看起来您正在 Office 自动化模型和您的代码之间有效地构建适配器层。因此,要调整您已有的内容:

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 缓存在列表中,以避免每次 Worksheets [=] 时都进行 SelectCast 调用26=] 被调用。

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