views:

441

answers:

6

I wrote a savefile method to save an object to xml. But I am not sure how to test the method in NUnit. Do I need create a sample file manually and compare the string between the files? Are there any better ways to test the method?

Thanks for your answer.

A: 

Here's what I do -- it works for me but it might not be to your specifications.

In the teardown I make sure I delete any files I might have created as part of the suite. So yes, make sure the file is a scratch file just for testing

In the test method I delete the file if it exists (it shouldn't as the teardown has already taken care of it), then output the file to XML then assert the file exists. I then reload the file either into an object graph or into the xml DOM and query the state through as many assertions as you need.

If you can get away with writing to files and your design allows you to write to a generic text writer or xml writer then you could bypass the file save and replace the calls with a string writer instead and just query a string. Much cleaner but it doesn't test that the actual file persistence is working or not.

Phil Bennett
+1  A: 

Ugh, validating XML output. Welcome to hell :)

A method that has worked for me was to generate an XmlDocument object in memory. Then run your SaveFile method, and load it into another XmlDocument. Walk both XmlDocuments recursively, comparing all elements and attributes.

Unfortunately, writing xml with C# objects is big and bulky. I'd recommend testing subsections at a time. Maybe your save file has a <FileList> sub element, a <Cups> sub element, and <Rifles> sub element. In that case, write a series of tests to ensure that each sub section is done correctly, instead of the overall output.

Robert P
+1  A: 

Here is a link to one of the related threads:

http://stackoverflow.com/questions/157917/creating-file-just-for-the-sake-on-unit-test

azamsharp
+1  A: 

It would be easier if you showed the code. My way around this, is to add a layer of abstraction. Do not have your Save method deal directly with XmlWriter. Instead create wrappers that will each be able to save small logical chunk of your data to xml, and test those.

for each Wrapper have a method like

void Persist(XmlWriter writer);

and let Save just collect the data from the wrappers. In other words, it would be Wrappers' responsibility to save the data properly, but each will be responsible just for the small chunk of it. There you can test it by comparing strings (put StringWriter into XmlWriter you pass into Persist method)

Krzysztof Koźmic
A: 

Design your class so that you have SaveFile( string fileName ) and SaveFile( XmlWriter writer). SaveFile( string filename ) only needs to create an XmlWriter for the named file and call SaveFile( writer ). Do your extensive unit testing on the SaveFile( XmlWriter writer ) method for which you can use a mock XmlWriter. Test some error conditions -- if you expect to handle them instead of propagate them up -- on the SaveFile( string filename ) method. Depending on the error handling you may not need to create a file at all.

BTW, you don't need to expose your method using the XmlWriter directly if you don't want to. You could make it private and use an accessor to invoke it in your tests.

tvanfosson
+1  A: 

Options

  1. Simplistic: Use 'Golden file' approach. Create a readonly expected output file as a resource. Do a byte/string wise compare with the actual generated file.
  2. I've heard some people use XmlUnit for this purpose. Never used it personally but might be worth taking a look at
Gishu