服务器.MapPath的单元测试

12

我有一个从硬盘中检索文档的方法。我无法在单元测试中测试它。它总是抛出异常,提示无效的空路径或其他什么异常。如何测试它?我临时为单元测试创建了会话,但我不能为这个 Server.MapPath 创建会话。该怎么办?


1
你不能。静态的东西很难模拟。考虑更改原始代码,需要从Server.MapPath获取值的部分,使用封装了Server.MapPath的Action委托。然后在测试中可以对此进行模拟。 - Marvin Smit
3
等一下!你之前曾经问过这个问题。-1 - Liam
@Liam,抱歉。但我无法理解那些人的回答。这就是为什么。 - Jeeva J
好的。我正在测试我的代码。但是在那段代码中,当控制流程到达Server.MapPath时,它总是返回null并抛出错误。如何找到解决方案? - Jeeva J
1
@JeevaJsb,我不确定我们可以说多少次,我将再次写出来,您需要模拟Server.MapPath。要模拟它,您需要更改代码,因为您无法模拟静态方法。Krzysztof Cieslak在下面提供了一个答案,您需要按照该答案所说的去做,没有其他要补充的。 - Liam
显示剩余8条评论
3个回答

36

您可以使用依赖注入和抽象来覆盖 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);
    }
}

10
使用 Path.Combine 而不是 + 进行字符串拼接。 - Marvin Smit
这里使用接口的好处是什么?相反,我们是否可以简单地创建两个类文件,并根据需要从实际应用程序和测试端点中调用它们?有人能否解释一下这个接口的好处? - Sebastian
1
点赞因为这是一个非常好的简单易懂的依赖注入示例。谢谢! - Nick DeMayo
抱歉,我不明白那如何有所帮助。在我的情况下,我正在对一个程序集进行单元测试,该程序集接受“~/”相对路径,并通过MapPath将其转换为绝对路径,而我不想更改程序集(它在Web项目中运行良好),我所需要做的就是提供有效的Http上下文以便在单元测试中使用该程序集。您正在调用HttpContext.Current.Server.MapPath,该方法属于ServerPathProvider - 但这在单元测试中不起作用,因为HttpContext.Current未初始化。 - Matt
这是一个非常好的、简单易懂的示例。 - Jeeva J
不硬编码的任何方式 - Sana Ahmed

10
如果您需要测试无法或不想更改的旧代码,可以尝试使用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? - djk
@Hannobo,目前的BasePath是AppDomain.CurrentDomain.BaseDirectory。如果您需要更改它,请在这里创建一个问题。 - vAD
你可以使用FakeHttpContext来执行HttpContext.Current.Server.MapPath("myPath").Should().Be(expectedPath); - Pedro S Cord

0

我正在使用NSubstitute,并按照以下方式实现:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接