Files as Embedded Resources in Unit Tests

One of the most common unit test mistakes that I see is using relative file paths to actual files. The problem with this is that tests run automatically as part of a build might not have the same file structure that your relative paths assume. A better solution is to use the DeploymentItem attribute in your tests to ensure the necessary resources are copied to the relevant unit test directory, but I prefer a different solution: compiling the files as embedded resources.

A file is added to the project as an embedded resource simply by changing its Build Action in Properties. Once it’s an embedded resource, it can be accessed from your unit tests like this:

private string GetFileContents(string sampleFile)
{
    var asm = Assembly.GetExecutingAssembly();
    var resource = string.Format("MyProject.Tests.SampleFiles.{0}", sampleFile);
    using (var stream = asm.GetManifestResourceStream(resource))
    {
        if (stream != null)
        {
            var reader = new StreamReader(stream);
            return reader.ReadToEnd();
        }
    }
    return string.Empty;
}

Note that the resource name is the Solution Explorer path to the file. So the above example is from a test project named “MyProject.Tests” in a folder named “SampleFiles.” This function accepts a file name and will return the contents of the specified file from that directory as a string.

This technique can be used in conjunction with mocks to simulate a multitude of scenarios like reading a file, retrieving data from a web service, or querying a database.

Here’s a quick example that demonstrates how this could be used to simulate retrieval of data from a web service:

public interface IDataAccess
{
	string GetXmlDataFromWebService();
}

public class MyClass
{
	private readonly IDataAccess _dataAccess;
	
	public MyClass(IDataAccess dataAccess)
	{
		_dataAccess = dataAccess;
	}
	
	public void Execute()
	{
		var xml = _dataAccess.GetXmlDataFromWebService();
		// do more...
	}
}

[TestMethod]
public void Execute_ProcessesXml()
{
	// Arrange
	var mockDataAccess = MockRepository.GenerateMock<IDataAccess>();
	var target = new MyClass(mockDataAccess);
	
	var xml = GetFileContents("TestData.xml");
	mockDataAccess.Expect(x => x.GetXmlDataFromWebService())
		.Return(xml);
	
	// Act
	target.Execute();
	
	// Assert
	mockDataAccess.VerifyAllExpectations();
	// more assertions...
}
Advertisement

Author: Adam Prescott

I'm enthusiastic and passionate about creating intuitive, great-looking software. I strive to find the simplest solutions to complex problems, and I embrace agile principles and test-driven development.

7 thoughts on “Files as Embedded Resources in Unit Tests”

  1. Awesome post. Just ran into this ‘issue’ today and this blog helped me a lot! Thanks!

  2. Just stumbled across this with a generic google search on embedded resources in unit tests. I remember now, you’re the one that taught me how to do it in the first place 8 years ago! Thanks for the lesson – and the re-lesson ;-).

    1. Ha! So funny. Well, if the internet is going to think I’m an expert on anything, I’m glad it’s embedded resources in unit tests 🙂

      Thanks for taking time to drop a note–I hope you’re doing well! (Well-wishing adjusted for 2020)

Leave a Reply to Adam Prescott Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: