我有一个测试控制器动作方法的单元测试方法。 action方法使用资源文件来获取静态消息。
message = Resources.MyResource.MemberNotVerified;
然而,在这一行,抛出的异常是: -
“无法加载文件或程序集'App_GlobalResources'或其依赖项之一。系统无法找到指定的文件。”:“App_GlobalResources”System.IO.IOException {System.IO.FileNotFoundException}
我尝试在我的测试项目中处理整个资源文件,但是没有成功 任何想法的朋友。
答案 0 :(得分:21)
在幕后, App_GlobalResources 使用 HttpContext.GetGlobalResourceObject
当然,单元测试中没有HttpContext(除非你嘲笑它)。
如果你倾向于嘲笑它,那么 Phil Haack 就会有一个不错的帖子here。
还有另一种解决方案,那就是将RESX文件移出常规目录。
Scott Allen 在帖子here上发帖。
答案 1 :(得分:4)
另一种方法是更改生成的资源文件的类型。
我希望还有其他方法可以设置它,但我们在文件的属性中设置了以下设置(右键单击解决方案资源管理器中的文件并选择属性):
答案 2 :(得分:1)
这是不需要更改任何内容的解决方案,因为它将生成一个名为App_GlobalResources.dll
的程序集,其中嵌入了所有资源,符合测试的期望。
只需从标有AssemblyInitialize
属性的方法中调用它,它将在所有测试开始之前仅运行一次:
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);
}