When I run the following code in my test,
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 understandably throws the following exception: System.NotSupportedException : Invalid verify on a non-virtual (overridable in VB) member: writer => writer.WriteAttributeString("ID", .language.LanguageID.ToString())
.
Stupid abstract XmlWriter
still has some non-abstract, non-virtual methods, like WriteAttributeString()
:(
I looked for an XmlWriterBase
or a System.Xml.Abstractions
, like I do for HttpContext
and Co., but found nothing :(
How would I overcome this so I can test that my WriteXml
method is doing what it's supposed to be doing?
As a rule of thumb, it is a bad idea to mock out classes you don't own, since you do not have a full control over them and that can result in problems (such as yours).
I think you can safely use a real XmlWriter
here that would write its output to a MemoryStream
and that simply assert that the stream contains the expected 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"));
}
The assertion part can be nicely refactored out to a helper method. Having recently written a code dealing with XML creating, I got burned on it pretty badly - at first, my tests were mock-based and essentialy, they were an exact copies of the production code. Fortunately, halfway through I've decided to refactor the whole thing to the style similar to one in my example and it really helped - tests are now much less fragile and everything is simpler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With