如何对需要特定文件的类进行单元测试

本文关键字:单元测试 文件 | 更新日期: 2023-09-27 18:26:24

我目前正在努力学习正确的单元测试。因此,现在我尝试为一个类编写单元测试,该类应该将数据从XML文件映射到适当的对象。当然,类的所有功能都取决于相应XML文件的存在。XML文件加载在类的构造函数中。

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

[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文件存在,同时请记住,失败的测试可能意味着它不存在?这在我看来是不对的。

有没有一个通用的模式来处理这样的问题?

感谢的帮助

edit:重写了第二个测试,因为如果文件真的存在,它就会失败。。。

edit2:希望它能告诉你设置阅读器的实际功能。到目前为止,它看起来是这样的:

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不会是这里的选择,是吗?

如何对需要特定文件的类进行单元测试

问题不在于单元测试,而在于类的设计。我建议重构类,这样它就不会打开文件,而是对流进行操作。然后,您的单元测试可以简单地将文件流替换为内存流-simples!:)

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("<settings>dummy settings</settings>"));

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

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

考虑重写代码,以便可以传入依赖项,或者以其他方式为要进行单元测试的代码存根。

例如,将类似"IMySettingsFileProvider"实例的内容传递给SettingsReader构造函数,其中IMySettingsFileProvider.SettingsXml返回一些设置流。通过这种方式,您可以为测试模拟IMySettingsFileProvider接口,而不需要文件出现在磁盘上。

一种选择是将其放在测试夹具的顶部。然后,只有当文件存在时,测试才会有效。

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