如何单元测试FileStream的File.Open

时间:2015-06-12 10:50:11

标签: c# unit-testing

首先,我熟悉单元测试模拟的概念,并且我根据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)));

问题是我在单元测试时readernull并且在应用程序中没有返回nodes

任何人都知道出了什么问题?

1 个答案:

答案 0 :(得分:6)

你在这里测试的问题是你有一个做两件事的方法:

  1. 打开并阅读文件内容。

  2. 从XmlDocument中读取您需要的节点。

  3. 您可能真正想要在此测试的是,您从特定文档中获得了预期的节点集。如果您将方法拆分为类似的东西,那么测试可能会更容易一些,然后您也可以使用只有一个责任的方法。您可以单独对装载器类进行单元测试,然后检查xml节点中的逻辑:

    class
    {   
    
        void LoadNodes(IFileLoader loader)
        {
             using(var reader = loader.GetReader()) 
             {
                  var nodes = XmlReaderUtils.EnumerateAxis(reader, new[] { "Node", "ArticleGroup" });
             }
    
        }
    }