views:

172

answers:

3

All: I have a unit test that is testing functionality that requires an input file. This test was built using VS 2008's built-in unit testing feature.

My problem is that the file needs to be discoverable by the unit test. However, when the test runs, it runs from a temporary "output" directory under the test results folder. It can't find my input file.

I have added the file to the unit test project, with a compile action of "none", and a copy to output directory option of "copy if newer", but the copy occurs to the normal VS output directory (under bin), and not to the unit test execution directory, so the file is not found. I don't want to hardcode paths to the file, as the test should run for anyone who checks out the unit test. I could put the input file in a solution folder, and let the test code "discover" the file by hardcoding a relative path back up the tree, but I figured that this had to be a common issue, so I wanted to check whether I was missing something.

+2  A: 

Add the file as a resource to your test assembly. Then you can load it at runtime via Assembly.GetManifestResourceStream in your test setup.

Here's a convenient method I use to load resources:

public static class ResLoader
{        
    public static string AsString<T>(string resName)
    {
         using (var reader = new StreamReader(Assembly.GetAssembly(typeof(T))
                                .GetManifestResourceStream(resName)))
        {
            return reader.ReadToEnd();
        }
    }
}

T is any class contained in your test assembly.

Todd Stout
+2  A: 

I typically Mock external resources like files and database results rather than try to access them in my unit tests. It's not always easy to do. Maybe if you show us the method in question we could help you make it more unit testable.

Matthew Vines
+2  A: 

You can use the DeploymentItem attribute to do this. There are a lot of caveats associated with it:

http://www.ademiller.com/blogs/tech/2007/10/gotchas-mstests-deploymentitem-attribute/

Alternatively you could add the file as a resource and read it from there. That's what I usually do.

Ade Miller