当我在测试中运行以下代码时,
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/