Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试:测试使用MapPath的方法_C#_.net_Unit Testing_Server.mappath - Fatal编程技术网

C# 单元测试:测试使用MapPath的方法

C# 单元测试:测试使用MapPath的方法,c#,.net,unit-testing,server.mappath,C#,.net,Unit Testing,Server.mappath,首先,我知道这个问题非常接近: 然而,我希望它有一个不同的解决方案。我的问题如下: 在我的代码中,我有一个需要验证的对象。我正在为每个验证方法创建单元测试,以确保其正确验证。我正在创建模拟数据并将其加载到对象中,然后对其进行验证。问题在于,在验证过程中,当发生错误时,会分配错误代码。此错误代码用于使用Server.MapPath从xml文件收集有关错误的信息。但是,在尝试获取xml文件时,会引发异常,这意味着无法找到该文件 既然MapPath在我的验证代码中,而不是在我的单元测试中,那么如何让

首先,我知道这个问题非常接近:

然而,我希望它有一个不同的解决方案。我的问题如下:

在我的代码中,我有一个需要验证的对象。我正在为每个验证方法创建单元测试,以确保其正确验证。我正在创建模拟数据并将其加载到对象中,然后对其进行验证。问题在于,在验证过程中,当发生错误时,会分配错误代码。此错误代码用于使用Server.MapPath从xml文件收集有关错误的信息。但是,在尝试获取xml文件时,会引发异常,这意味着无法找到该文件

既然MapPath在我的验证代码中,而不是在我的单元测试中,那么如何让单元测试识别路径呢?这个问题有意义吗

错误行(在我的验证代码中,而不是在我的单元测试中):


简化:单元测试在我的程序中调用一个方法,该方法调用Server.MapPath,然后失败。

尝试使用Rhino Mock或其他模拟框架来模拟httpContext(或其他依赖对象) 或者您可以编写自己的模拟对象。 或者编写一个MapPathWrapper类,从真实环境的MapPathWrapper基类继承,然后在单元测试中创建一个MockMapPathWrapper对象

应该有很多这样的嘲弄的例子

我问了一个问题:

更新 我只在Asp.Net MVC上有过这样的经验,在webforms I imagein中,由于缺少HttpContextBase类,这将非常困难。

我会将“文件名提供程序”抽象为一个只返回位置的类,然后您可以非常轻松地模拟它

public class PathProvider
{
    public virtual string GetPath()
    {
        return HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml");
    }
}
然后,您可以直接使用PathProvider类

PathProvider pathProvider = new PathProvider();
XDocument xdoc = XDocument.Load(pathProvider.GetPath());
或者在测试中模拟它:

PathProvider pathProvider = new MockPathProvider(); // using a mocking framework
XDocument xdoc = XDocument.Load(pathProvider.GetPath());

我将提取接受依赖项作为参数的方法:

public void Validate(HttpContext context)
{
    ValidatePath(context.Server.MapPath("App_Data/ErrorCodes.xml"));
}

public void ValidatePath(string path)
{
    XDocument xdoc = XDocument.Load(path);
    ValidateDocument(xdoc);
}

public void ValidateDocument(XDocument xdoc)
{
    // Original code
}

然后可以独立测试各种方法。例如,测试
ValidatePath()
如何处理丢失的文件。

经过严格的谷歌搜索和同事的帮助,我们找到了一个简单的解决方案,该解决方案已经内置到.net中

在访问验证过程的单元测试之上,我添加了:

 [TestMethod()]
 [HostType("ASP.NET")]
 [UrlToTest("http://localhost:###/upload_file.aspx")]
 [AspNetDevelopmentServerHost("Path To Web Application", "Path To Web Root")]

这很好用。基本上,当调用测试时,它会在页面加载中加载带有指定单元测试的URL。由于它是一个正在调用单元测试的网站,因此验证将可以访问Server.MapPath。这个解决方案可能不适用于所有人,但它是完美的。感谢您的贡献。

GetPath()应该是虚拟的。@Dan HttpContext.Current。从TestProject运行时返回null。有没有办法避免这种情况?@JibinMathew是的,不要使用
HttpContext.Current
。我知道这听起来很滑稽,但这是真的。通常,不要模拟您不拥有的类,但您可以为
HttpContextBase
编写一个包装类,它实现您想要的功能。@DanAtkinsonHOW@Sana我不知道这是不是一个问题。如果需要,请检查是否已经回答,如果没有,请将其作为问题而不是评论进行提问。这样的集成测试对于确保所有部分协同工作非常有用,但此解决方案无法处理其他情况(如缺少文件)。生成测试web应用程序也是一项相当昂贵的操作,如果您经常运行测试,这会增加成本。同意,虽然此解决方案在运行时可以提供有用的信息,但它不是任何意义上的单元测试,并且缺少实际单元测试的大部分好处。这是一个非常节省时间的解决方案!!
 [TestMethod()]
 [HostType("ASP.NET")]
 [UrlToTest("http://localhost:###/upload_file.aspx")]
 [AspNetDevelopmentServerHost("Path To Web Application", "Path To Web Root")]