首先,我熟悉单元测试模拟的概念,并且我根据TDD编写了一个应用程序。
我有一个方法,我需要读取一个文件。 读入文件:
using (var webshopXmlFileStream = StreamFactory.Create(importFile))
{
// Opens a reader that will read the Xml file.
using (var reader = XmlReader.Create(webshopXmlFileStream))
{
// Read the nodes "Node" and "ArticleGroup" recursively.
var nodes = XmlReaderUtils.EnumerateAxis(reader, new[] { "Node", "ArticleGroup" });
}
}
当然,这不是单元可测试的。
所以,我创建了一个名为IStreamFactory
的接口,它只有一个方法:
Stream Create(string filePath);
此界面的实现如下:
public Stream Create(string filePath)
{
return File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
}
所以,现在我可以模拟界面返回MemoryStream
,如下所示:
const string webshopXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<Node>" +
"<Name></Name>" +
"</Node>";
var streamFactoryMock = new Mock<IStreamFactory>();
streamFactoryMock.Setup(action => action.Create(It.IsAny<string>())).Returns((string input) => new MemoryStream(Encoding.ASCII.GetBytes(webshopXmlData)));
问题是我在单元测试时reader
是null
并且在应用程序中没有返回nodes
。
任何人都知道出了什么问题?
答案 0 :(得分:6)
你在这里测试的问题是你有一个做两件事的方法:
打开并阅读文件内容。
从XmlDocument中读取您需要的节点。
您可能真正想要在此测试的是,您从特定文档中获得了预期的节点集。如果您将方法拆分为类似的东西,那么测试可能会更容易一些,然后您也可以使用只有一个责任的方法。您可以单独对装载器类进行单元测试,然后检查xml节点中的逻辑:
class
{
void LoadNodes(IFileLoader loader)
{
using(var reader = loader.GetReader())
{
var nodes = XmlReaderUtils.EnumerateAxis(reader, new[] { "Node", "ArticleGroup" });
}
}
}