如何在C#中进行unit testing中的MapPath

我想在unit testing中加载外部XML文件,以测试该XML上的一些处理代码。 如何获取文件的路径?

通常在网络应用程序中我会这样做:

XDocument.Load(Server.MapPath("/myFile.xml")); 

但显然在我的unit testing中我没有引用Server或HttpContext,所以如何映射路径以便我不必指定完整路径?

更新:

我只想说明我实际测试的代码是针对XML解析器类的,类似于:

 public static class CustomerXmlParser { public static Customer ParseXml(XDocument xdoc) { //... } } 

所以为了测试这个,我需要解析一个有效的XDocument。 正在测试的方法不会访问文件系统本身。 我可以直接在测试代码中从String创建XDocument,但我认为从文件中加载它会更容易。

另一个想法是利用dependency injection。

 public interface IPathMapper { string MapPath(string relativePath); } 

然后简单地使用2个实现

 public class ServerPathMapper : IPathMapper { public string MapPath(string relativePath){ return HttpContext.Current.Server.MapPath(relativePath); } } 

然后你还需要你的模拟实现

 public class DummyPathMapper : IPathMapper { public string MapPath(string relativePath){ return "C:/Basedir/" + relativePath; } } 

然后,所有需要映射路径的函数只需要访问IPathMapper的实例 – 在您的Web应用程序中它需要是ServerPathMapper,并在您的单元中测试DummyPathMapper – 基本DI(dependency injection)。

就个人而言,我会非常谨慎地拥有依赖于后端资源存储的任何代码,无论是文件系统还是数据库 – 您在unit testing中引入了一个可能导致漏报的依赖项,即测试失败不是因为您的特定测试代码,而是因为文件不存在或服务器不可用等。
请参阅此链接,了解IMO对unit testing的详细定义,更重要的是不是

您的unit testing应该测试一个primefaces的,定义明确的function,而不是测试文件是否可以加载。 一种解决方案是“模拟”文件加载 – 但是有各种方法,但我个人只是模拟你正在使用的文件系统的接口,而不是尝试做任何完整的文件系统模拟 – 这是一个很好的SOpost和这是关于文件系统模拟的一个很好的SO讨论

希望有所帮助

通常对于unit testing,我将xml文件作为嵌入资源添加到项目中,并使用如下方法加载它们:

 public static string LoadResource(string name) { Type thisType = MethodBase.GetCurrentMethod().DeclaringType; string fullName = thisType.Namespace + "." + name + ".xml"; using (Stream stream = thisType.Module.Assembly.GetManifestResourceStream(fullName)) { if(stream==null) { throw new ArgumentException("Resource "+name+" not found."); } StreamReader sr = new StreamReader(stream); return sr.ReadToEnd(); } } 

编辑:我从头开始,因为我想我最初以错误的方式解释你的问题。

在unit testing中加载XML文件以便将其注入到某些类中的最佳方法是在MSunit testing中使用DeploymentItem属性。

这将如下所示:

 [TestMethod] [DeploymentItem(@"DataXmlFiles\MyTestFile.xml", "DataFiles")] public void LoadXMLFileTest() { //instead of "object" use your returning type (ie string, XDocument or whatever) //LoadXmlFile could be a method in the unit test that actually loads an XML file from the File system object myLoadedFile = LoadXmlFile(Path.Combine(TestContext.TestDeploymentDir, "DataFiles\\MyTestFile.xml")); //do some unit test assertions to verify the outcome } 

我现在没有在调试器上测试代码,但它应该可以工作。

编辑:顺便说一下,当你使用DeploymentItem时,请在这里考虑这篇文章。

类别:

 internal class FakeHttpContext : HttpContextBase { public override HttpRequestBase Request { get { return new FakeHttpRequest(); } } } internal class FakeHttpRequest : HttpRequestBase { public override string MapPath(string virtualPath) { return /* your mock */ } } 

用法:

 [TestMethod] public void TestMethod() { var context = new FakeHttpContext(); string pathToFile = context.Request.MapPath("~/static/all.js"); }