c# - 如何用最小起订量模拟 System.Xml.XmlWriter.WriteAttributeString()?

标签 c# mocking nunit moq xmlwriter

当我在测试中运行以下代码时,

Mock<XmlWriter> mockXmlWriter = new Mock<System.Xml.XmlWriter>();
Language language = Language.GetLangauge(langId);
language.WriteXml(mockXmlWriter.Object);
mockXmlWriter.Verify(writer => writer.WriteAttributeString("ID", language.LanguageID.ToString()));

Moq 可以理解地抛出以下异常:System.NotSupportedException:对非虚拟(在 VB 中可覆盖)成员的验证无效:writer => writer.WriteAttributeString("ID", .language.LanguageID.ToString() )

愚蠢的抽象 XmlWriter 仍然有一些非抽象、非虚拟的方法,比如 WriteAttributeString() :(

我寻找了一个 XmlWriterBase 或一个 System.Xml.Abstractions,就像我为 HttpContext 和 Co. 做的那样,但什么也没找到: (

我该如何克服这个问题,以便我可以测试我的 WriteXml 方法是否正在执行它应该执行的操作?

最佳答案

根据经验,模拟不属于您的类是个坏主意,因为您无法完全控制它们并且可能会导致问题(例如您的问题)。

我认为您可以在这里安全地使用真正的 XmlWriter,它将其输出写入 MemoryStream 并简单地断言该流包含预期的 XML:

// arrange
MemoryStream underlyingStream = new MemoryStream();
XmlWriter xmlWriter = XmlWriter.Create(underlyingStream);
Language language = Language.GetLangauge(langId);

// act
language.WriteXml(xmlWriter);

// assert
underlyingStream.Position = 0;
using (StreamReader streamReader = new StreamReader(underlyingStream)
{
    string createdXml = streamReader.ReadToEnd();
    Assert.That(createdXml, Is.EqualTo("expectedXml"));
}

断言部分可以很好地重构为辅助方法。最近写了一段处理 XML 创建的代码,我对它非常厌烦——起初,我的测试是基于模拟的,本质上,它们是生产代码的精确副本。幸运的是,中途我决定将整个事情重构为与我的示例中的风格相似的风格,这确实很有帮助 - 测试现在不那么脆弱,一切都变得更简单。

关于c# - 如何用最小起订量模拟 System.Xml.XmlWriter.WriteAttributeString()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13866064/

相关文章:

c# - 在 MVC 4 .NET 类中获取操作 URL

c# - 使用泛型并在接口(interface)中实现可选字段或选择性地实现接口(interface)?

c# - 从您打算测试的类继承是否总是次优的?

python - 如何修补 python 方法以运行测试用例?

c# - NUnit:在单个测试中运行多个断言

c# - Web API 2 自定义身份验证

mocking - 有人让痣正常工作了吗?

c# - Moq 和 nUnit 测试 Entity Framework MVC 3 C#

c# - 在 NUnit 测试中获取上下文

c# - 使用导航属性的 T-SQL 到 LINQ to SQL