C# 如何在C中映射单元测试中的路径#
我想在单元测试中加载一个外部XML文件,以测试该XML上的一些处理代码。如何获取文件的路径 通常在web应用程序中,我会:C# 如何在C中映射单元测试中的路径#,c#,C#,我想在单元测试中加载一个外部XML文件,以测试该XML上的一些处理代码。如何获取文件的路径 通常在web应用程序中,我会: XDocument.Load(Server.MapPath("/myFile.xml")); 但很明显,在我的单元测试中,我没有对服务器或HttpContext的引用,所以我如何映射路径,从而不必指定完整路径 更新: 我只想说明,我实际测试的代码是针对XML解析器类的,比如: public static class CustomerXmlParser { public
XDocument.Load(Server.MapPath("/myFile.xml"));
但很明显,在我的单元测试中,我没有对服务器或HttpContext的引用,所以我如何映射路径,从而不必指定完整路径
更新:
我只想说明,我实际测试的代码是针对XML解析器类的,比如:
public static class CustomerXmlParser {
public static Customer ParseXml(XDocument xdoc) {
//...
}
}
所以为了测试这一点,我需要解析一个有效的XDocument。正在测试的方法不访问文件系统本身。我可以直接从测试代码中的字符串创建XDocument,但我认为从文件加载它会更容易。就我个人而言,我对任何依赖后端的代码都非常谨慎 资源存储,无论是文件系统还是数据库-您在单元测试中引入的依赖关系可能导致误判,即测试失败不是因为您的特定测试代码,而是因为文件不存在或服务器不可用等。
对于什么是单元测试,更重要的是什么不是单元测试,IMO对此有一个很好的定义 您的单元测试应该测试一个原子的、定义良好的功能,而不是测试一个文件是否可以加载。 一种解决方案是“模拟”文件加载—有多种方法可以实现这一点,但我个人只会模拟您正在使用的文件系统的接口,而不会尝试进行任何完整的文件系统模拟—这是一篇关于文件系统模拟的好文章,也是一篇关于文件系统模拟的好讨论
希望对您有所帮助通常对于单元测试,我会将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();
}
}
另一个想法是利用依赖注入
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(依赖项注入)编辑:我从零开始,因为我想我一开始对你的问题的理解是错误的 在单元测试中加载XML文件以便将其注入某些类的最佳方法是在MS单元测试中使用DeploymentItem属性 如下所示:
[TestMethod]
[DeploymentItem(@"DataXmlFiles\MyTestFile.xml", "DataFiles")]
public void LoadXMLFileTest()
{
//instead of "object" use your returning type (i.e. 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
}
我现在没有在调试器上测试代码,但它应该可以工作
编辑:
顺便说一下,当您使用DealMyTimeTm考虑这个帖子时,类:
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");
}
这可能对某人有帮助。我有一个相关的问题。想要使用我的c#单元测试项目中根级别文件夹中的Excel文件 我有一个名为“TestFiles”的根级别文件夹。里面有“Test.xlsx” 我所做的是: 右键单击“Test.xlsx”,转到属性并设置“复制到输出目录”=“始终复制” 现在,文件及其包含文件夹“TestFiles”总是被复制到单元测试项目的bin文件夹中。所以我可以这样使用它:
var filePath = "TestFiles/Test.xlsx";
var strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=0\"";
using (var conn = new OleDbConnection(strConn))
{
conn.Open();
...
}
需要明确的是,我不是在测试是否可以加载XML或测试文件的内容,而是在测试一段需要解析XDocument的代码。文件与测试一起定位如果它没有加载,那么测试将显示错误,而不是假阴性。我意识到这并不理想,但我不知道还有其他方法。我已经更新了我的问题。当然这是重点,不是吗?您的代码正在测试解析器,因此它从何处获取xml数据是无关的,并且不会因为文件不存在而失败。就我个人而言,我会选择字符串选项,或者您可以将其作为嵌入式资源使用。这里的接口有什么好处?。相反,我们可以简单地创建2个类文件并相应地调用它们吗?1个来自实际应用程序,1个来自测试端点?有人能在这里解释一下这个接口的好处吗?通过使用类,您需要决定让一个类继承另一个类,以使类型系统满意。让您的测试实现继承真实的实现,或者以另一种方式进行,这并不是一个理想的解决方案。通过这种方式,您根本不需要让您的真实实现和测试实现相互了解——它们只是需要满足一个公共接口。