如何对需要特定文件的类进行unit testing

我目前正在努力学习正确的unit testing。 所以现在我正在尝试为一个类编写unit testing,该类应该将XML-File中的数据映射到正确的对象。 当然,该类的所有function都取决于相应XML文件的存在。 XML文件加载在类的构造函数中。

我正在使用C#和NUnit。 到目前为止,我有两个测试:

[Test] public void ShouldAllowInstanceToBeCreatedWhenXMLFileIsPresent() { if (File.Exists(SettingsReader.XML_SETTINGS_PATH)) { SettingsReader settingsReader = new SettingsReader(); Assert.AreNotEqual(null, settingsReader); } } [Test] [ExpectedException("Telekanzlei.Clientmanager.XMLDataLayer.XMLFileNotFoundException")] public void ShouldThrowExceptionWhenXMLFileIsNotPresent() { if (!File.Exists(SettingsReader.XML_SETTINGS_PATH)) { SettingsReader settingsReader = new SettingsReader(); } else throw new XMLFileNotFoundException(); } 

我不确定在测试中检查文件是否存在是正确的方法,所以对这些测试的任何建议也是受欢迎的。 但我的问题是,如何进行以下测试。 如果XML文件不存在,显然所有后续测试都将失败。

那么我是否认为XML文件存在,同时请记住,失败的测试可能只是意味着它不是? 这对我来说似乎不对。

是否有一般模式来处理这样的问题?

感谢任何帮助

编辑:重写第二个测试,因为如果文件实际存在则失败…

edit2:可能有助于告诉你,SettingsReader实际上做了什么。 到目前为止它看起来像这样:

 public class SettingsReader { public static readonly string XML_SETTINGS_PATH = "C:\\Telekanzlei\\Clientmanager_2.0\\Settings.xml"; public XElement RootXElement { get; private set; } public SettingsReader() { if (!File.Exists(XML_SETTINGS_PATH)) throw new XMLFileNotFoundException(); using (var fs = File.OpenRead(XML_SETTINGS_PATH)) { RootXElement = XElement.Load(fs); } } } 

我不确定,但我猜一个StreamReader不会是去这里的方式,不是吗?

问题不在于您的unit testing,而在于类的设计。 我建议重构该类,以便它不会打开文件,而是在流上运行。 然后你的unit testing可以简单地替换内存流的文件流 – 简单! 🙂

 public class SettingsReader() { public SettingsReader(System.IO.StreamReader reader) { // read contents of stream... } } // In production code: new SettingsReader(new StreamReader(File.Open("settings.xml"))); // In unit test: new SettingsReader(new StringReader("dummy settings")); 

请记住,打开文件和解析设置数据是两个非常不同的问题。

如果您必须我建议您使用SetUp方法来复制或validation该文件是否存在。 我建议通过将文件添加到测试项目并将其标记为“始终复制”来确保文件存在,一旦您完成工作,就无需重新检查它。
如果你有很多需要外部文件的测试,你可能应该使用MsTest – 它有一个名为DeploymentItem的属性,它确保将文件复制到与测试相同的位置。

考虑重写代码,以便可以传入依赖关系,或者以某种方式为您要进行unit testing的代码存根。

即将“IMySettingsFileProvider”实例传递给SettingsReader构造函数,其中IMySettingsFileProvider.SettingsXml返回一些设置流。 这样,您可以模拟IMySettingsFileProvider接口进行测试,而不是要求文件存在于磁盘上。

一种选择是将它放在测试夹具的顶部。 然后测试仅在文件存在时才有效。

 [SetUp] public void Setup() { Assume.That(File.Exists(SettingsReader.XML_SETTINGS_PATH)); }