我正在尝试单元测试保存文件。我有一个定义文档的接口,我将实现该接口的具体对象传递给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,但是模拟接口会序列化吗?
答案 0 :(得分:1)
BinaryFormatter在序列化数据时使用传入的对象的实际类型 - 而不是接口。所以在内部它会在你传递一个真实对象时写出类似Type:MyLib.Objects.MyObj,MyLib的东西,并在你传递一个模拟对象时输入:Moq.ConcreteProxy,Moq等。
使用BinaryFormatter进行持久化会让您遇到麻烦,因为您必须处理版本之间的版本控制和内存布局差异。为文档建立一个定义良好的格式并手动编写对象和字段会更好。
答案 1 :(得分:0)
如果您需要测试序列化如何与类一起工作,那么为测试创建一些真正的类并使用它们。模拟对于测试协作对象之间的交互非常有用。