0

我的代码如下所示:

public class FileFormatLookup : Dictionary<string,Func<string>>
{
    private Workbook workbook;
    private MemoryStream memoryStream;

    public  FileFormatLookup(Workbook workbook, MemoryStream memoryStream)
    {
        this.workbook = workbook;
        this.memoryStream = memoryStream;
        Add();
    }

    private void Add()
    {
        base.Add("xls", () =>
                            {
                                workbook.Save(memoryStream, SaveFormat.Excel97To2003);
                                return "ms-excel";
                            });
    }
}

我正在尝试编写如下测试:

class FileFormatLookupTest
{
    FileFormatLookup fileFormatLookup;
    private Workbook workbook;
    private MemoryStream memoryStream;

    [SetUp]
    public void SetUp()
    {
        fileFormatLookup = new FileFormatLookup(workbook, memoryStream);
        workbook = MockRepository.GenerateMock<Workbook>();
        memoryStream = MockRepository.GenerateMock<MemoryStream>();
    }

    [TearDown]
    public void TearDown()
    {
      workbook.VerifyAllExpectations();
    }


    [Test]
    public void ShouldHaveXlsKey()
    {
        var xlsResult = fileFormatLookup["xls"].Invoke();
        workbook.AssertWasCalled(x=>x.Save(memoryStream,SaveFormat.Excel97To2003));
     }
}

这是在字典中测试函子的正确方法吗?它抛出此错误:

System.InvalidOperationException : No expectations were setup to be verified, ensure that the method call in the action is a virtual (C#) / overridable (VB.Net) method call

如何测试返回函数的字典?是否可以?我可以断言返回的字符串值,但不能断言方法调用。

4

1 回答 1

3

您没有将模拟传递给正在测试的课程。

将设置更改为

[SetUp]
public void SetUp()
{
    workbook = MockRepository.GenerateMock<Workbook>();
    memoryStream = MockRepository.GenerateMock<MemoryStream>();
    fileFormatLookup = new FileFormatLookup(workbook, memoryStream);
}

从错误消息来看,似乎需要设置期望,即调用您期望的模拟对象。在这种情况下workbook.Save(...)

为此,workbook.Save(...)必须是虚拟的或在接口上。


编辑:在作为评论提供更多信息后。

如果workbook.Save(...)它不是虚拟的并且不在您的代码中,您必须走一条稍长的路线才能测试该对象。

创建您自己的IWorkbook实现该Save()方法的接口,然后创建一个WorkbookWrapper包含第 3 方Workbook类实例的类,并IWorkbook通过将调用转发到包装类来实现。

public interface IWorkbook
{
    void Save(...);
}

class WorkbookWrapper : IWorkbook
{
    private _workbook;

    public WorkbookWrapper(...)
    {
        _workbook = new Workbook(...);
    }

    public void Save(...)
    {
        _workbook.Save(...);
    }
}

然后更改您的代码以IWorkbook取而代之:

private Workbook _workbook;

public FileFormatLookup(IWorkbook workbook, MemoryStream memoryStream)
{
    _workbook = workbook;
    _memoryStream = memoryStream;
    Add();
}

然后,您可以对其他类使用相同的技术,例如MemoryStream.

于 2013-01-21T07:24:52.203 回答