"App_GlobalResources" not loading in a Unit test case

Here's a solution that doesn't require changing anything, as it will generate an assembly named App_GlobalResources.dll with all the resources embedded, the way the tests expect.

Just call it from a method marked with the AssemblyInitialize attribute and it will run only once, before all tests start:

public static void GenerateResourceAssembly()
{
    var testExecutionFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

    var solutionRootPath = "PATH_TO_YOUR_SOLUTION_ROOT";

    //Somewhere similar to C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
    var pathResgen = "PATH_TO_RESGEN.EXE"; 

    //You may need to adjust to the path where your global resources are
    var globalResourcesPath = Path.Combine(solutionRootPath, @"Web\App_GlobalResources");

    var parameters = new CompilerParameters
    {
        GenerateExecutable = false,
        OutputAssembly = "App_GlobalResources.dll"
    };

    foreach (var pathResx in Directory.EnumerateFiles(globalResourcesPath, "*.resx"))
    {
        var resxFileInfo = new FileInfo(pathResx);

        var filename = resxFileInfo.Name.Replace(".resx", ".resources");

        var pathResources = Path.Combine(testExecutionFolder, "Resources." + filename);

        var startInfo = new ProcessStartInfo
        {
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            FileName = Path.Combine(pathResgen, "resgen.exe"),
            Arguments = string.Format("\"{0}\" \"{1}\"", pathResx, pathResources)
        };

        using (var resgen = Process.Start(startInfo))
        {
            resgen.WaitForExit();
        }

        parameters.EmbeddedResources.Add(pathResources);
    }

    CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(parameters);
}

An alternative approach is to change the type of resource file your generating.

I expect there are other ways of setting it up but we set the following settings in the file's properties (right click on the file in the solution explorer and select properties):

  • Build Action: Embedded Resource
  • Copy to Output Directory: Do not copy
  • Custom Tool: PublicResXFileCodeGenerator
  • Resources: Resources

Behind the scenes, App_GlobalResources uses HttpContext.GetGlobalResourceObject

Of course, there is no HttpContext in unit tests (unless your mocking it).

If you were so inclined to mock it, Phil Haack has a decent post on it here.

There is another solution, and that is to move the RESX files out of the regular directory.

Scott Allen has a post on that here.