【问题标题】:Unit testing for Server.MapPathServer.MapPath 的单元测试
【发布时间】:2013-11-02 23:50:48
【问题描述】:

我有一个方法。从硬盘中检索文件。我无法从单元测试中对此进行测试。它总是抛出异常无效的空路径或其他东西。如何测试。我暂时为单元测试创​​建了会话。但我不能为这个 Server.MapPath。该怎么做?

【问题讨论】:

  • 你需要模拟服务器对象,This question 谈到了它,虽然这是针对 MVC 你应该仍然能够应用相同的逻辑。
  • 你不能。静力学有点难以模拟。考虑更改需要来自 Server.MapPath 的值的原始代码以采用封装 Server.MapPath 的 Action 委托。然后在你的测试中你可以模拟这个。
  • 是的,就像@MarvinSmit 所说,您需要转向依赖注入模式来实现这一目标
  • @JeevaJsb,我不知道我们可以说多少次,我会再写一遍,你需要模拟 Server.MapPath。要模拟它,您需要更改代码,因为您无法模拟静态方法。 Krzysztof Cieslak 在下面提供了一个答案,您需要按照该答案所说的去做,没有什么可以补充的。

标签: c# unit-testing


【解决方案1】:

您可以在 Server.MapPath 上使用依赖注入和抽象

public interface IPathProvider
{
   string MapPath(string path);
}

生产实施将是:

public class ServerPathProvider : IPathProvider
{
     public string MapPath(string path)
     {
          return HttpContext.Current.Server.MapPath(path);
     }
}

在测试一个时:

public class TestPathProvider : IPathProvider
{
    public string MapPath(string path)
    {
        return Path.Combine(@"C:\project\",path);
    }
}

【讨论】:

  • 咳嗽 Path.Combine 而不是 +
  • 接口在这里有什么好处?相反,我们是否可以简单地制作 2 个类文件并相应地调用它们 1 从实际应用程序和 1 从测试端点调用?有人可以在这里解释这个界面的好处吗?
  • 赞成,因为这是一个非常简单、易于理解的依赖注入示例。谢谢!
  • 抱歉,我看不出这有什么帮助。就我而言,我正在对一个程序集进行单元测试,该程序集又接受内部的“~/”相对路径,通过 MapPath 将它们转换为绝对路径,我不想更改程序集(它在 Web 项目中工作正常),所有我需要做的是提供一个有效的 Http 上下文,以便能够在单元测试中使用程序集。您在属于 ServerPathProvider 的 MapPath 中调用 HttpContext.Current.Server.MapPath - 但这在单元测试中不起作用,因为 HttpContext.Current 未初始化。
  • 这是一个简单易懂的好示例。
【解决方案2】:

如果您需要测试无法或不想更改的遗留代码,可以尝试FakeHttpContext

这就是它的工作原理:

var expectedPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "path");
using (new FakeHttpContext())
{
    var mappedPath = Http.Context.Current.Server.MapPath("path");
    Assert.Equal(expectedPath, mappedPath);
}

【讨论】:

  • 如何用 FakeHttpContext设置基础 MapPath?
  • @Hannobo,当前 BasePath 为 AppDomain.CurrentDomain.BaseDirectory。如果您需要更改它,请创建一个问题here
  • 你可以使用这个 HttpContext.Current.Server.MapPath("myPath").Should().Be(expectedPath);使用 FakeHttpContext
【解决方案3】:

我使用的是 NSubstitute,我实现如下:

 var fakeContext = Substitute.For<HttpContextBase>();
fakeContext.Server.MapPath(Arg.Any<string>()).ReturnsForAnyArgs("/set-path/");

【讨论】:

    猜你喜欢
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多