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

发布于 2024-07-30 13:47:33 字数 654 浏览 3 评论 0原文

首先,我知道这个问题非常接近: 如何在 C# 单元测试中映射路径

I但我希望它有不同的解决方案。 我的问题如下:

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

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

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

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

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

First of all, I am aware that this question is dangerously close to:
How to MapPath in a unit test in C#

I'm hoping however, that it has a different solution. My issue follows:

In my code I have an object that needs to be validated. I am creating unit tests for each validation method to make sure it is validating correctly. I am creating mock data and loading it into the object, then validating it. The problem is that within the validation, when an error occurs, an error code is assigned. This error code is used to gather information about the error from an xml file using Server.MapPath. However, when trying to get the xml file, an exception is thrown meaning the file cannot be found.

Since MapPath is in my validation code, and not my unit test, how do I get my unit test to recognize the path? Does this question make sense?

Error Line (In my Validation code NOT my unit test):

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

Simplified: The Unit Test calls a method in my program that calls Server.MapPath which then fails.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

牵你手 2024-08-06 13:47:33

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

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

I would abstract out the "filename provider" into an class that simply returns a location, then you can mock it much, much easier.

public class PathProvider
{
    public virtual string GetPath()
    {
        return HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml");
    }
}

Then, you can either use the PathProvider class directly...

PathProvider pathProvider = new PathProvider();
XDocument xdoc = XDocument.Load(pathProvider.GetPath());

Or mock it out in your tests:

PathProvider pathProvider = new MockPathProvider(); // using a mocking framework
XDocument xdoc = XDocument.Load(pathProvider.GetPath());
甜警司 2024-08-06 13:47:33

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

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

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

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

After some rigorous googling and some help from a colleague we came up with a simple solution already built into .net

Above the unit tests that accesses the validation process, I added:

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

This works perfectly. Basically, when the test is called, it loads the URL with the specified unit test in the page load. Since it is a web site that is now calling the unit test, the validation will have access to Server.MapPath. This solution may not work for everyone, but it was perfect for this. Thanks to all you contributed.

安静 2024-08-06 13:47:33

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

应该有很多嘲笑 SO 的例子。

这是我问的一个问题:

如何使用 Rhino Mocks 进行 Mock HttpContext.Application

更新
我只有使用 Asp.Net MVC 执行此操作的经验,使用 Webforms 我认为由于缺少 HttpContextBase 类,这会困难得多。

Try using Rhino Mocks or an alternative mocking framework to Mock the httpContext (or other dependent objects)
Or you could write your own mock objects.
Or write a MapPathWrapper class, inherit from a MapPathWrapperBase class for your real environment, then in for your unit tests create a MockMapPathWrapper object.

There should be plenty of examples for mocking on SO.

Here's one I asked:

How to use Rhino Mocks to Mock an HttpContext.Application

UPDATE
I only have experience doing this with the Asp.Net MVC, with webforms I imagein it would be a lot more difficult because of the lack of an HttpContextBase class.

醉酒的小男人 2024-08-06 13:47:33

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

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

I would extract methods that accept your dependencies as arguments:

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
}

You can then test the various methods independently. For example, testing how ValidatePath() handles a missing file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文