C# 单元测试:测试使用 MapPath 的方法
-
12-09-2019 - |
题
首先,我知道这个问题非常接近:如何在 C# 单元测试中映射路径
但我希望它有不同的解决方案。我的问题如下:
在我的代码中,我有一个需要验证的对象。我正在为每种验证方法创建单元测试,以确保其正确验证。我正在创建模拟数据并将其加载到对象中,然后验证它。问题是在验证过程中,当发生错误时,会分配一个错误代码。此错误代码用于使用 Server.MapPath 从 xml 文件收集有关错误的信息。但是,当尝试获取 xml 文件时,会抛出异常,意味着找不到该文件。
由于 MapPath 位于我的验证代码中,而不是我的单元测试中,因此如何让我的单元测试识别该路径?这个问题有意义吗?
错误行(在我的验证代码中,而不是我的单元测试中):
XDocument xdoc = XDocument.Load(HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml"));
简化:单元测试调用我的程序中的一个方法,该方法调用 Server.MapPath,然后失败。
解决方案
我将抽象出了“名商”成只返回一个位置的类,然后就可以多嘲笑它,容易多了。
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());
其他提示
在一些严格的google搜索,并从同事一些帮助,我们想出了已经内置到.NET
一个简单的解决方案上面访问验证过程的单元测试,我添加:
[TestMethod()]
[HostType("ASP.NET")]
[UrlToTest("http://localhost:###/upload_file.aspx")]
[AspNetDevelopmentServerHost("Path To Web Application", "Path To Web Root")]
此完美。基本上,当测试被调用时,它加载在页面加载指定的单元测试的URL。由于它是一个网站,现在要求的单元测试,验证将有机会获得使用Server.Mappath。该解决方案可能不适合每一个人,但它是为这个完美的。感谢您做出贡献的所有。
尝试使用犀牛模拟或替代模拟框架模拟HTTPContext(或其他因对象),或者您可以编写自己的模拟对象。或者编写一个 MapPathWrapper 类,从真实环境的 MapPathWrapperBase 类继承,然后在单元测试中创建一个 MockMapPathWrapper 对象。
应该有很多嘲笑 SO 的例子。
这是我问过的一个:
如何使用 Rhino Mocks 来模拟 HttpContext.Application
更新我只有使用 Asp.Net MVC 执行此操作的经验,使用 Webforms 我认为由于缺少 HttpContextBase 类,这会困难得多。
我想提取接受你的依赖关系为参数的方法:
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()
处理丢失的文件。