Tao Gómez Gil
Tao Gómez Gil

Reputation: 2735

Unit test method that takes FileInfo as a parameter

I have a method that takes a FileInfo object as parameter and checks whether the corresponding file is encoded in UTF-8.

I have written some unit tests for it with MSTest using real text files added to the UnitTest project, which are deployed with the DeploymentItem attribute. I then create FileInfo objects pointing to the deployed files and test the method with them. Like this:

    [TestMethod]
    [DeploymentItem(@"..\..\Import\UTF8.txt")]
    public void TestUTF8Detection()
    {
        FileInfo fileInfo = new FileInfo("UTF8.txt");
        bool isUTF8= FormatVerification.IsUTF8(fileInfo);
        Assert.IsTrue(isUTF8);
    }

However, I've read that using real files could be slower and less trustworthy (like here and here), so I'm thinking how would I do this mocking the files. I think I would have to:

So, I have some questions, from more concrete to more general:

  1. How can I create a FileStream object encoded in UTF-8 without a real file to read from?
  2. Is the creation of this sub-method the only alternative to allow mocking the files?
  3. What about the original method? Can I test it in some way?
  4. Is creating this sort of sub-methods (only to allow unit testing ) considered to be a good practice?
  5. Should I really try to avoid using real files in unit tests, or are there cases like this one which justify it?

Upvotes: 0

Views: 1678

Answers (2)

Patrick Allwood
Patrick Allwood

Reputation: 1832

FileInfo is sealed, so you can't do the inherit and override trick.

I'd use something like SystemWrapper, or roll my own interface for FileInfo, in the same way Haukinger suggests, and then once your code depends on the interface it should be easy to mock the behaviour you need.

Upvotes: 1

Haukinger
Haukinger

Reputation: 10873

I guess your best bet is to abstract the FileInfo into an IMyFileInfo together with a factory that creates those from filenames (that is, it creates the original FileInfo plus a wrapper).

The test can then create a mock IMyFileInfo). Your interface/wrapper should expose everything from the FileInfo that you need within IsUTF8.

The production code should then use the factory instead of new to create wrappers instead of real FileInfos.

Upvotes: 0

Related Questions