Server.MapPath 的单元测试

Posted

技术标签:

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

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

【问题讨论】:

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

【讨论】:

以上是关于Server.MapPath 的单元测试的主要内容,如果未能解决你的问题,请参考以下文章

.NET 单元测试的艺术&单元测试之道C#版

什么是单元测试?如何做好单元测试?

测试篇——初探单元测试

单元测试

单元测试2

Java单元测试介绍