Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"App_GlobalResources" not loading in a Unit test case


I have a unit test method which tests a controller action method. The action method uses resource file to get a static message.

 message = Resources.MyResource.MemberNotVerified;

However at this line the exception thrown is :-

"Could not load file or assembly 'App_GlobalResources' or one of its dependencies. The system cannot find the file specified.":"App_GlobalResources" System.IO.IOException {System.IO.FileNotFoundException}

I tried coping the whole resource file in my Test project, but it was unsuccessful.
Any idea friends.

like image 821
SocialCircus Avatar asked Nov 11 '10 11:11

SocialCircus


3 Answers

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.

like image 113
RPM1984 Avatar answered Oct 21 '22 14:10

RPM1984


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
like image 4
Patrick Avatar answered Oct 21 '22 13:10

Patrick


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);
}
like image 2
Anderson Pimentel Avatar answered Oct 21 '22 13:10

Anderson Pimentel