Reputation:
I'm trying to get into the unit testing and TDD way of doing things but I've come across a problem I'm not sure what to do with.
I have a collection that saves itself to disk using XDocument and XmlWriter. I know you shouldn't write the file to disk then check it so I had the XmlWriter output to a memory stream then I checked the contents of the memory stream. The function looks like this:
public void Save()
{
using (XmlWriter xmlWriter = XmlWriter.Create(m_StreamProvider.SaveFileStream(m_FilenameProvider.Filename)))
{
XDocument xDoc = new XDocument(new XElement("BookmarkCollection",
Items.Select(bookmark => new XElement("Bookmark",
new XElement("Name", bookmark.Name),
new XElement("Link", bookmark.Link),
new XElement("Remarks", bookmark.Remarks),
new XElement("DateAdded", bookmark.DateAdded),
new XElement("DateLastAccessed", bookmark.DateLastAccessed))
)
));
xDoc.Save(xmlWriter);
}
}
And the unit test is
[Test]
public void Save_OneItemCollection_XmlCreatedCorrectly()
{
//Arrange
MemoryStreamProvider streamProvider = new MemoryStreamProvider();
IBookmarkCollection collection = XBookmarkTestHelpers.GetXBookmarkCollection(streamProvider);
IBookmark bookmarkToAdd = XBookmarkTestHelpers.GetIBookmark("myLink");
collection.Add(bookmarkToAdd);
//Act
collection.Save();
//Assert
streamProvider.WriteStrean.Position = 0;
String generatedXml = Encoding.Default.GetString(streamProvider.WriteStrean.GetBuffer());
Assert.IsTrue(String.Equals(generatedXml, m_ExpectedOneItemString), "XML does not match");
}
The assert here fails too fragile (I know I could use String.Compare() but it would have similar issues.), Am I testing the right thing? Am I mocking the wrong thing?
All input greatly appreciated!
Upvotes: 5
Views: 1493
Reputation: 1039100
The first thing that feels wrong about the Save function is that it actually has two responsibilities: it selects a storage and it serializes an object graph to this storage. I would start by isolating responsibilities:
public void Save(XmlWriter xmlWriter)
{
XDocument xDoc = new XDocument(new XElement("BookmarkCollection",
Items.Select(bookmark => new XElement("Bookmark",
new XElement("Name", bookmark.Name),
new XElement("Link", bookmark.Link),
new XElement("Remarks", bookmark.Remarks),
new XElement("DateAdded", bookmark.DateAdded),
new XElement("DateLastAccessed", bookmark.DateLastAccessed))
)
));
xDoc.Save(xmlWriter);
}
public void Save()
{
using (XmlWriter xmlWriter = XmlWriter.Create(m_StreamProvider.SaveFileStream(m_FilenameProvider.Filename)))
{
Save(xmlWriter);
}
}
As far as the unit test is concerned, you could define an XSD schema and then validate the result XML against this schema and also test that it contains the values you are looking for.
Upvotes: 5
Reputation: 233197
In such cases, I use XNode.DeepEquals to compare XML instances with each other because it compares structure, not bytes.
Upvotes: 1