Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test class that reads xml file?

I need to write a unit tests for a class that reads a xml file and parses it's content. How can I Mock the file reading ? Because all the content of the tests should be against read file .

I use nmock2 with nUnit.

Thanks

like image 341
Night Walker Avatar asked Jun 13 '10 07:06

Night Walker


2 Answers

As rwwilden suggests, life is a lot easier if you use a stream-based API instead of a filename-based one. Using mocking isn't terribly appropriate here, IMO; you're not doing "protocol testing" - you just want a data source.

You can also provide an overload which is a simple utility method:

 public Result ParseXml(string file)
 {
     using (Stream stream = File.OpenRead(file))
     {
         return ParseXml(stream);
     }
 }

You could then reasonably safely not test that method - it has no significant logic in it, after all.

Now you could test the stream-based API by using a hard-coded string in your code, then calling Encoding.UTF8.GetBytes(xml) and building a MemoryStream around the resulting byte array... but I generally prefer to use separate data files in my test project. Set the content type to "embedded resource" and then use Assembly.GetManifestResourceStream to obtain a stream to the test file.

If this is genuinely a normal XML file though, do you really want to do the parsing yourself? Is there any reason you don't want to leave that to the framework, and express your API either in terms of the DOM API, LINQ to XML, or XmlReader?

like image 188
Jon Skeet Avatar answered Sep 18 '22 10:09

Jon Skeet


All you have to do is find a way to tell your class what file to read. So it depends a little on how your class is implemented. The easiest approach would be something like this:

public class ClassToTest : IClassToTest
{
    public Result ParseXml(Stream xml)
    {
        // Parse xml and return result.
        return ...;
    }
}

[Test]
public void TestParseXml()
{
    // Get xml stream to test from somewhere.
    Stream xmlStream = ...;

    // Call method to test.
    var result = new ClassToTest().ParseXml(xmlStream);

    // Assert results.
    Assert.IsNotNull(result);
    ...
}

The idea is that you somehow provide the class you are testing with an xml file that you created and for which you know what parse results to expect.

like image 40
Ronald Wildenberg Avatar answered Sep 20 '22 10:09

Ronald Wildenberg