Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何对需要显示特定文件的类进行单元测试_C#_Unit Testing_Nunit - Fatal编程技术网

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

C# 如何对需要显示特定文件的类进行单元测试,c#,unit-testing,nunit,C#,Unit Testing,Nunit,我目前正在努力学习正确的单元测试。因此,现在我尝试为一个类编写单元测试,该类应该将数据从XML文件映射到适当的对象。当然,该类的所有功能都依赖于相应XML文件的存在。XML文件加载到类的构造函数中 我在用C#和NUnit。到目前为止,我有两个测试: [Test] public void ShouldAllowInstanceToBeCreatedWhenXMLFileIsPresent() { if (File.Exists(SettingsReader.XML_SETTINGS_PAT

我目前正在努力学习正确的单元测试。因此,现在我尝试为一个类编写单元测试,该类应该将数据从XML文件映射到适当的对象。当然,该类的所有功能都依赖于相应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文件存在,同时记住,测试失败可能意味着它不存在?那对我来说似乎不合适

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

谢谢你的帮助

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

编辑2:也许这有助于告诉你,设置阅读器实际上是做什么的。目前看来是这样的:

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不适合这里,是吗?

如果必须,我建议您使用安装方法复制或验证文件是否存在。 我建议将该文件添加到测试项目中,并将其标记为“始终复制”,以确保该文件存在。一旦该文件开始工作,则无需重新检查。

如果您有许多需要外部文件的测试,也许您应该使用MsTest-它有一个名为DeploymentItem的属性,确保将文件复制到与测试相同的位置。

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


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

问题不在于单元测试,而在于类的设计。我建议重构该类,使其不打开文件,而是在流上操作。然后,您的单元测试可以简单地将文件流替换为内存流-simples!:)

公共类设置阅读器()
{
公共设置读卡器(System.IO.StreamReader读卡器)
{
//读取流的内容。。。
}
}
//在生产代码中:
新的设置阅读器(新的StreamReader(File.Open(“settings.xml”));
//单元测试中:
新设置阅读器(新StringReader(“虚拟设置”);

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

一个选项是将其放在测试夹具的顶部。那么测试只有在文件存在时才有效

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

SettingsReader是否设计为使用依赖项注入?听起来是DI的一个很好的例子,mocking.MSTest有[DeploymentItem]用于此。也许NUnit有类似的东西?这不是有点“过火”吗?XML文件仅由这个类使用。仅为加载文件而创建接口+类?同意。我不明白为什么人们会因为嘲笑是“纯粹”的方式而增加这么多的复杂性。你最好利用创建文件的代码来创建它/将它复制到临时位置,使用它,然后删除它。是的,它可能是。这就是为什么我试着写“考虑…”——如果它对您的案例有效,那么就这样做,如果没有,那么就做其他事情(这已经被建议作为早期的答案)。我刚刚意识到XElement.Load-method将流作为参数。我还不太熟悉.NET。但你的建议似乎是个好办法。所以我将把它拆分成一个SettingsStreamProvider类和一个SettingsParser类,并对解析器使用依赖注入?一个setting stream provider类对一个普通流有什么价值?我认为这将是一个毫无意义的抽象-KISS:)要点^^问题是我在项目中多次使用SettingsReader,但总是使用同一个XML文件。我不太喜欢每次使用时“手动”创建一个新流。这就是为什么我想在SettingsReader类中首先处理流打开的原因……但我想我还是采用了你的方法。通过使用StringReader建议,我可以测试对损坏的xml文件的反应,而不必提供损坏的文件。嗯,在这种情况下,我会考虑使用某种设置管理器类。。我通常不提倡单身,但这将是一个很好的候选人。然后,无论何时需要加载/保存设置,您都有一个单一的联系人。经理将负责打开文件并将流传递给阅读器。。。
[SetUp]
public void Setup()
{
    Assume.That(File.Exists(SettingsReader.XML_SETTINGS_PATH));
}