简体   繁体   English

一个单元如何测试修改XML文档?

[英]How does one unit test modifying an XML document?

I'm at a loss for how to even begin creating unit tests for this method: 我不知道如何开始为该方法创建单元测试:

public override void ModifyXmlDocument(Foo foo, string nodeToChange, string newValue)
{
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.Load(foo.XmlPathAndFileName);
    XmlElement rootElement = xmlDocument.DocumentElement;
    // rest of method (to modify an XML doc) here
}

That method simply finds the element/node in an XML doc and updates it with the user-supplied value. 该方法只是在XML文档中找到元素/节点,并使用用户提供的值对其进行更新。 (The method is more complex than what is shown here.) (该方法比此处显示的要复杂。)

The part that I'm having a hard time with is understanding how to have this method execute, without relying on the hard disk. 我很难过的部分是了解如何执行此方法,而不依赖于硬盘。 But xmlDocument.Load() takes a file path and loads a file from disk. 但是xmlDocument.Load()采用文件路径并从磁盘加载文件。 At the end of the method, it saves the updated file back to disk. 方法结束时,它将更新的文件保存回磁盘。

How can I make this method unit testable? 如何使该方法单元可测试?

There are a couple of ways you can do this, but all require a refactoring of your code. 有两种方法可以执行此操作,但是所有方法都需要重构代码。 ModifyXmlDocument will need to take XmlDocument as a parameter, then you can mock it from there on. ModifyXmlDocument将需要将XmlDocument作为参数,然后可以从那里对其进行模拟。

public void test_that_xml_is_loaded()
{
    var sut = new SUT();
    var xmldocumentfake = new Mock<XmlDocument>(){CallBase=true};
    xmldocumentfake.Setup(x=>x.LoadXml(It.IsAny<String>()));

    sut.ModifyXmlDocument(foo, nodeToChange, newValue, xmlDocumentfake.Object);

   xmldocumentfake.Verify(x=>x.LoadXml(It.IsAny<String>()), Times.Once());
}

You could also wrap the XmlDocument in another class that you can write as an abstraction that can be modified. 您也可以将XmlDocument包装在另一个类中,该类可以编写为可以修改的抽象。 Again, you would have to pass it in, though. 同样,您必须将其传递。

Also, as Anthony Pegram had alluded and what I mean: be careful that you are not breaking the Single Responsibility Principle . 同样,正如安东尼·佩格拉姆(Anthony Pegram)所说的和我的意思:请注意不要违反单一责任原则 When tests are too hard to write, that is often a scream that you have broken that principle. 当测试太难编写时,通常是您违反了该原则的尖叫。

A couple of options: 有两个选择:

  • If you are using VS2012 Ultimate, you can use the Fakes to create a shim that will override the behavior when XmlDocument opens the file. 如果您使用的是VS2012 Ultimate,则可以使用Fakes创建一个填充文件,该填充文件将在XmlDocument打开文件时覆盖其行为。
  • When you are testing, deploy a sample XML file with your unit tests. 在测试时,请在单元测试中部署示例XML文件。 Then when passing in a Foo instance, use the path to that file. 然后,当传入Foo实例时,请使用该文件的路径。
  • Try one of the alternates to XmlDocument.Load such as one that takes a stream or XmlReader. 尝试使用XmlDocument.Load的替代项之一,例如采用流或XmlReader的替代项。 Then create that with a method that you can override. 然后使用可以覆盖的方法来创建它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM