# Friday, June 04, 2004

I have been writing a lot of code lately that involves parsing external files, like XSD and WSDL files.  In my unit tests, I need to be able to read in a sample file that I can use to run the unit tests off of.  The problem is my unit tests (using NUnit) get run in several different places: my local dev sandbox, the build server, etc.  That makes it hard to know where to get the test XSD/WSDL files that I need to run the NUnit tests.  Hard coded, absolute paths don't work, because people may have their code in different places on different machines, and the tests should still pass.  Relative paths don't work either, since the test assemblies sometimes run from where VS.NET puts them (xxx/bin/Debug) and sometimes from the build directory, which is a totally different location.

The solution I finally hit upon was to use embedded resources.  Add your external file to your VS.NET project, and make its "Build Action" = "Embedded Resource".  That way, the file will get embedded into your final assembly as a "manifest resource".  

With that done, your test code can write out that embedded resource to a known location every time (like the temp directory) and use that for testing, cleaning up after itself when it's done.

In the following example, the external file is called "Example.wsdl".  It gets written out to the temp directory, then deleted when all the tests are done using the SetUp and TearDown methods.

    public class TestWsdl
    {
        private string wsdlPath = Path.Combine(Path.GetTempPath(),"Example.wsdl");
        private Wsdl wsdl = null;
    
        public TestWsdl()
        {
        }

        [SetUp()]
        public void Unpack()
        {
            Assembly a = Assembly.GetExecutingAssembly();
            Stream s = a.GetManifestResourceStream("MyNamespace.Test.Example.wsdl");
            StreamReader sr = new StreamReader(s);
            StreamWriter sw = File.CreateText(wsdlPath);
            sw.Write(sr.ReadToEnd());
            sw.Flush();
            sw.Close();
            sr.Close();
        }

        [TearDown()]
        public void CleanUp()
        {
            if(File.Exists(wsdlPath))
            {
                File.Delete(wsdlPath);
            }
        }

The only tricky part can be figuring out the name of your manifest resource to pass to GetManifestResourceStream.  It should be the default namespace for your project plus the filename.  The easiest way to find out what it is is to use Reflector, which lists all the resouces in any given assembly.

Friday, June 04, 2004 10:40:24 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |