19

首先,我知道这个问题非常接近: 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

4 回答 4

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());
于 2009-08-11T17:30:18.690 回答
11

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

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

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

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

于 2009-08-11T20:33:33.500 回答
1

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

应该有很多模拟 SO 的例子。

这是我问的一个:

如何使用 Rhino Mocks 模拟 HttpContext.Application

更新 我只有使用 Asp.Net MVC 执行此操作的经验,使用我想象的 webforms 会因为缺少 HttpContextBase 类而变得更加困难。

于 2009-08-11T17:22:58.457 回答
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()处理丢失的文件。

于 2009-08-11T17:41:36.640 回答