如何对一个返回函数的字典进行单元测试

本文关键字:函数 字典 单元测试 返回 一个 | 更新日期: 2023-09-27 17:54:39

代码如下:

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

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

如何对一个返回函数的字典进行单元测试

您没有将mock传递给正在测试的类。

将设置更改为

[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类,其中包含第三方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 .