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

时间:2009-08-11 17:07:36

标签: c# .net unit-testing server.mappath

首先,我知道这个问题非常危险: How to MapPath in a unit test in C#

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

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

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

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

XDocument xdoc = XDocument.Load(HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml"));

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

4 个答案:

答案 0 :(得分:15)

我会将“文件名提供程序”抽象为一个只返回一个位置的类,然后你可以更加容易地模拟它。

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());

答案 1 :(得分:11)

经过严格的谷歌搜索和一位同事的帮助,我们想出了一个已经内置于.net的简单解决方案

在访问验证过程的单元测试之上,我补充说:

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

这完美无缺。基本上,在调用测试时,它会在页面加载中使用指定的单元测试加载URL。由于它是一个现在调用单元测试的网站,因此验证将可以访问Server.MapPath。这个解决方案可能并不适用于所有人,但它对此非常有用。感谢你所做的贡献。

答案 2 :(得分:1)

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

应该有很多关于模仿的例子。

这是我问过的一个:

How to use Rhino Mocks to Mock an HttpContext.Application

<强>更新 我只有使用Asp.Net MVC的经验,使用webforms我会因为缺少HttpContextBase类而变得更加困难。

答案 3 :(得分:1)

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

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()如何处理丢失的文件。