一个模拟的界面仍然会序列化到一个文件?

时间:2009-05-11 20:30:52

标签: c# unit-testing serialization mocking

我正在尝试单元测试保存文件。我有一个定义文档的接口,我将实现该接口的具体对象传递给Save方法,并且它在实践中有效,但我正在尝试对其进行单元测试以确保它始终有效(并且我'在一段“关键时刻”之后,我拼命想要赶上单元测试。)

我的保存方法很简单,它的工作原理如下:

public Boolean SaveDocument(IDocument document)
{
    BinaryFormatter bFormatter = new BinaryFormatter();
    FileStream fs = null;

    try
    {
        if (!Directory.Exists(folderName))
            Directory.CreateDirectory(folderName);

        String path = Path.Combine(Path.Combine(folderName, document.FileName), document.Extension);
        using (fs = new FileStream(path, FileMode.OpenOrCreate))
        {
            bFormatter.Serialize(fs, document);
        }
    }
    catch (IOException ioex)
    {
        LOG.Write(ioex.Message);
        return false;
    }

    return true;
}

我的测试是:

[Test]
public void can_save_a_document()
{
    String testDirectory = "C:\\Test\\";
    m_DocumentHandler = new DocumentHandler(testDirectory);

    DynamicMock mock = new DynamicMock(typeof(IDocument));

    mock.ExpectAndReturn("get_FileName", "Test_File");
    mock.ExpectAndReturn("get_Extension", ".TST");

    m_DocumentHandler.SaveDocument(mock.MockInstance as IDocument);

    try
    {    
        Assert.IsTrue(Directory.Exists(testDirectory), "Directory was not created");
        String[] filesInTestDir = Directory.GetFiles(testDirectory);

        Assert.AreEqual(1, filesInTestDir.Length, "there is " + filesInTestDir.Length.ToString() + " files in the folder, instead of 1");
        Assert.AreEqual(Path.GetFileName(filesInTestDir[0]), "Test_File.TST");
    }
    finally
    {
        Directory.Delete(testDirectory);
        Assert.IsFalse(Directory.Exists(testDirectory), "folder was not cleaned up");
    }
}

我知道序列化接口preserves the concrete data,但是模拟接口会序列化吗?

2 个答案:

答案 0 :(得分:1)

BinaryFormatter在序列化数据时使用传入的对象的实际类型 - 而不是接口。所以在内部它会在你传递一个真实对象时写出类似Type:MyLib.Objects.MyObj,MyLib的东西,并在你传递一个模拟对象时输入:Moq.ConcreteProxy,Moq等。

使用BinaryFormatter进行持久化会让您遇到麻烦,因为您必须处理版本之间的版本控制和内存布局差异。为文档建立一个定义良好的格式并手动编写对象和字段会更好。

答案 1 :(得分:0)

如果您需要测试序列化如何与类一起工作,那么为测试创建一些真正的类并使用它们。模拟对于测试协作对象之间的交互非常有用。