Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Including resources file for Unit test in C# project

I have some functions that read and modify files. In order to make the unit tests independent of any file system issues, I want to include the files inside the project.

However, my function should be getting the filePath, and all I can get from the assembly is a FileStream. Any idea how I can get the file path of a resource file in the project?

System.Reflection.Assembly a = System.Reflection.Assembly.Load(assemblyName);
FileStream stream = a.GetFile(assemblyName + "." + fileName);
like image 548
Yossale Avatar asked Jul 20 '10 12:07

Yossale


2 Answers

My usual solution for this problem is that I refactor my program to open the file in the calling method and then pass a Stream instead of passing the filename and opening the file there.

For testing, this allows me to pass a MemoryStream so I can write my unit test without using the file system at all. It's sometimes even easier to check if the data has been written correctly and it's definitely faster, especially for a higher number of tests. You just have to remember to flush the MemoryStream after writing as .NET doesn't always do this automatically.

Example from one of my programs:

public TestSaveAndLoad()
{
  [... create data to save ...]
  using (MemoryStream targetStream = new MemoryStream())
  {
    target.Save(targetStream);
    targetStream.Flush();
    targetStream.Seek(0, ...);
    target.Load(targetStream);
  }
  [... assert that the loaded data equals the saved data ...]
}
like image 81
Morfildur Avatar answered Sep 20 '22 13:09

Morfildur


An embedded resource doesn't exist on the file system, so it doesn't have any file path.

You have two options:

  • Change the API of your SUT so that it accepts a Stream instead of only a file path. This solution is much preferred.
  • Save the embedded resource to a temporary file during unit testing, making sure to delete it again after each test case.

The first solution is an excellent example of how TDD drives us towards better, more flexible APIs.

like image 21
Mark Seemann Avatar answered Sep 20 '22 13:09

Mark Seemann