在ASP.NETunit testing中模拟HttpContext.server.MapPath

我在ASP.Net Web应用程序中进行unit testing,现在我在模型文件中访问我的构造函数来测试哪个有用于上传我的XML文件的Server.MapPath代码,当试图测试这个我得到错误时,因为HttpContext为null所以我不得不嘲笑Server.MapPath。

我搜索了很多,但每个样本仅为Asp.NET MVC提供,但我在ASP.NET工作。 所以请帮助ASP.NET解决这个问题。

我的代码如下。

public class NugetPlatformModel { public bool IsHavingLicense { get; set; } public List PlatformProduct = new List(); public NugetPlatformModel() { var xmldoc = new XmlDocument(); mldoc.Load(HttpContext.Current.Server.MapPath(@"~\Content\PlatformProducts.xml")); } } 

我的unit testing代码

  [Test] public void Account_UnlicensedCustomerIdentity_IsStudioLicenseAndIshavinglicenseFalse() { //Act NugetPlatformModel nugetPlatformModel = new NugetPlatformModel(); //Assert AssertEquals(false, nugetPlatformModel.IsHavingLicense); } 

这是典型的代码调用静态方法,在保持关注点分离和避免紧密耦合的同时进行测试非常困难。 这是一种测试和模拟“不可测试代码”的通用方法:为它编写一个“外观包装器”。

  • 为这些方法创建一个包装器。 一个简单的类,包含名为sensibly的方法,并且只委托给untestable调用(通常是静态调用)

  • 创建该包装类的接口

  • 不要直接在客户端代码中调用untestable方法,而是使用包装器(使用步骤2中提供的接口进行dependency injection)并在其上调用常规方法。

  • 在您的unit testing中,使用您想要的行为模拟包装器。

这种方法有效地减少了耦合并分离了需要分离的问题。 当然,您仍然无法测试包装器本身的行为,但如果它足够简单(仅委托给原始调用)那么它就不是一个大问题了。

更新:

使用填充程序将应用程序与其他程序集隔离以进行unit testing

填充类型是Microsoft Fakes Framework使用的两种技术之一,可让您轻松地将测试中的组件与环境隔离。 垫片将调用转移到特定方法,以编写您作为测试的一部分编写的代码。 许多方法根据外部条件返回不同的结果,但是垫片在测试的控制之下,并且可以在每次调用时返回一致的结果。 这使您的测试更容易编写。 使用填充程序将代码与不属于解决方案的程序集隔离开来。 要将解决方案的组件彼此隔离,我们建议您使用存根。

如何回答,你应该解耦你的系统

 public class NugetPlatformModel { public bool IsHavingLicense { get; set; } public List PlatformProduct = new List(); public NugetPlatformModel(IPlatformProductProvider provider) { var xmldoc = new XmlDocument(); //System.Web.HttpContext.Current.Server.MapPath(@"~\Content\PlatformProducts.xml") xmldoc.Load(provider.Filepath); } public interface IPlatformProductProvider { string Filepath { get; } } public class PlatformProductProvider: IPlatformProductProvider { string _filepath; public string Filepath { get { return _filepath; } set { _filepath = value;} } public PlatformProductProvider(string path) { _filepath = path; } } } 

你的测试可能是:

 [Test] public void Account_UnlicensedCustomerIdentity_IsStudioLicenseAndIshavinglicenseFalse() { //Arrange // using Moq //var mock = new Mock(); //IPlatformProductProvider provider = mock.Object; //provider.Filepath = "pippo.xml"; // otherwise var provider = new PlatformProductProvider("pippo.xml"); //Act NugetPlatformModel nugetPlatformModel = new NugetPlatformModel(provider); //Assert AssertEquals(false, nugetPlatformModel.IsHavingLicense); } 

如果您无法修改源代码,请尝试使用填充程序( https://msdn.microsoft.com/en-us/library/hh549176.aspx )。