如何测试 XML De-/Serialization
How to test XML De-/Serialization
所以我尝试创建一个非常简单的 XmlFileWriter
public class XmlFileWriter
{
public void WriteTo<TSerializationData>(string path, TSerializationData data)
{
using (StreamWriter streamWriter = new StreamWriter(path))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(TSerializationData));
xmlSerializer.Serialize(streamWriter, data);
}
}
}
和XmlFileReader
public class XmlFileReader
{
public TSerializationData ReadFrom<TSerializationData>(string path)
{
using (StreamReader streamReader = new StreamReader(path))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(TSerializationData));
return (TSerializationData) xmlSerializer.Deserialize(streamReader);
}
}
}
我想用 xUnit 为它们创建单元测试。由于它们与文件系统耦合,我一直在寻找一种以某种方式模拟它的方法。许多帖子强烈推荐 System.IO.Abstractions 包和额外的 TestingHelpers.
我现在只展示 reader 的测试,因为这两种情况非常相似。这是我目前所拥有的
[Fact]
public void ThrowsExceptionIfPathIsInvalid()
{
XmlFileReader xmlFileReader = new XmlFileReader();
// use an empty path since it should be invalid
Assert.Throws<Exception>(() => xmlFileReader.ReadFrom<object>(string.Empty));
}
[Fact]
public void DeserializesDataFromXmlFile()
{
// Generate dummy data with default values
MyDummyClass dummyData = new MyDummyClass();
XmlFileWriter xmlFileWriter = new XmlFileWriter();
XmlFileReader xmlFileReader = new XmlFileReader();
string filePath = "???"; // TODO
// Generate a new file and use it as a mock file
xmlFileWriter.WriteTo(filePath, dummyData);
// Read from that file
MyDummyClass fileContent = xmlFileReader.ReadFrom<MyDummyClass>(filePath);
// Compare the result
Assert.Equal(dummyData, fileContent);
}
我正在努力解耦真正的文件系统。我如何让 XmlSerializer
class 使用伪造的文件系统?我安装了抽象包,但我不知道如何在这种情况下使用它(用于读写)。
StreamReader
and StreamWriter
both have constructors that accept a Stream. I recommend making your method also take streams as parameters, and the your unit tests can supply a MemoryStream
containing your test xml as a string (which can be hardcoded), while your actual application can provide a FileStream
即磁盘上的文件。像这样:
public void WriteTo<TSerializationData>(Stream location, TSerializationData data)
{
// Code here doesn't change
}
public TSerializationData ReadFrom<TSerializationData>(Stream location)
{
// Code here doesn't change
}
然后在你的测试中你可以做:
using (var ms = new MemoryStream())
{
using (var sr = new StreamWriter())
{
sr.Write("<xml>This is your dummy XML string, can be anything you want</xml>");
}
MyDummyClass fileContent = xmlFileReader.ReadFrom<MyDummyClass>(ms);
}
如果你想从文件中读取,你可以这样做:
// Using whatever FileMode/ FileAccess you need
MyDummyClass fileContent;
using (var fs = File.Open(@"C:\Path\To\File.xml", FileMode.Open, FileAccess.Read))
{
fileContent = xmlFileReader.ReadFrom<MyDummyClass>(fs);
}
所以我尝试创建一个非常简单的 XmlFileWriter
public class XmlFileWriter
{
public void WriteTo<TSerializationData>(string path, TSerializationData data)
{
using (StreamWriter streamWriter = new StreamWriter(path))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(TSerializationData));
xmlSerializer.Serialize(streamWriter, data);
}
}
}
和XmlFileReader
public class XmlFileReader
{
public TSerializationData ReadFrom<TSerializationData>(string path)
{
using (StreamReader streamReader = new StreamReader(path))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(TSerializationData));
return (TSerializationData) xmlSerializer.Deserialize(streamReader);
}
}
}
我想用 xUnit 为它们创建单元测试。由于它们与文件系统耦合,我一直在寻找一种以某种方式模拟它的方法。许多帖子强烈推荐 System.IO.Abstractions 包和额外的 TestingHelpers.
我现在只展示 reader 的测试,因为这两种情况非常相似。这是我目前所拥有的
[Fact]
public void ThrowsExceptionIfPathIsInvalid()
{
XmlFileReader xmlFileReader = new XmlFileReader();
// use an empty path since it should be invalid
Assert.Throws<Exception>(() => xmlFileReader.ReadFrom<object>(string.Empty));
}
[Fact]
public void DeserializesDataFromXmlFile()
{
// Generate dummy data with default values
MyDummyClass dummyData = new MyDummyClass();
XmlFileWriter xmlFileWriter = new XmlFileWriter();
XmlFileReader xmlFileReader = new XmlFileReader();
string filePath = "???"; // TODO
// Generate a new file and use it as a mock file
xmlFileWriter.WriteTo(filePath, dummyData);
// Read from that file
MyDummyClass fileContent = xmlFileReader.ReadFrom<MyDummyClass>(filePath);
// Compare the result
Assert.Equal(dummyData, fileContent);
}
我正在努力解耦真正的文件系统。我如何让 XmlSerializer
class 使用伪造的文件系统?我安装了抽象包,但我不知道如何在这种情况下使用它(用于读写)。
StreamReader
and StreamWriter
both have constructors that accept a Stream. I recommend making your method also take streams as parameters, and the your unit tests can supply a MemoryStream
containing your test xml as a string (which can be hardcoded), while your actual application can provide a FileStream
即磁盘上的文件。像这样:
public void WriteTo<TSerializationData>(Stream location, TSerializationData data)
{
// Code here doesn't change
}
public TSerializationData ReadFrom<TSerializationData>(Stream location)
{
// Code here doesn't change
}
然后在你的测试中你可以做:
using (var ms = new MemoryStream())
{
using (var sr = new StreamWriter())
{
sr.Write("<xml>This is your dummy XML string, can be anything you want</xml>");
}
MyDummyClass fileContent = xmlFileReader.ReadFrom<MyDummyClass>(ms);
}
如果你想从文件中读取,你可以这样做:
// Using whatever FileMode/ FileAccess you need
MyDummyClass fileContent;
using (var fs = File.Open(@"C:\Path\To\File.xml", FileMode.Open, FileAccess.Read))
{
fileContent = xmlFileReader.ReadFrom<MyDummyClass>(fs);
}