在ASP.NET单元测试中模拟HttpContext.server.MapPath

时间:2015-03-09 12:28:19

标签: c# asp.net asp.net-mvc unit-testing

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

我已经搜索了很多,但每个样本仅针对Asp.NET MVC,但我在ASP.NET中工作过。所以请帮助ASP.NET解决这个问题。

我的代码如下。

public class NugetPlatformModel
{
    public bool IsHavingLicense { get; set; }
    public List<PlatformProducts> PlatformProduct = new List<PlatformProducts>();
    public NugetPlatformModel()
    {
      var xmldoc = new XmlDocument();

       mldoc.Load(HttpContext.Current.Server.MapPath(@"~\Content\PlatformProducts.xml"));
    }
}

我的单元测试代码

 [Test]
    public void Account_UnlicensedCustomerIdentity_IsStudioLicenseAndIshavinglicenseFalse()
    {

        //Act
        NugetPlatformModel nugetPlatformModel = new NugetPlatformModel();

        //Assert
        AssertEquals(false, nugetPlatformModel.IsHavingLicense);

    }

3 个答案:

答案 0 :(得分:3)

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

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

  • 创建该包装类的接口

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

  • 在您的单元测试中,使用您想要的行为模拟包装器。

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

更新

Using shims to isolate your application from other assemblies for unit testing

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

答案 1 :(得分:2)

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

public class NugetPlatformModel
  {
    public bool IsHavingLicense { get; set; }
    public List<PlatformProducts> PlatformProduct = new List<PlatformProducts>();
    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>();
      //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);

    }

答案 2 :(得分:1)

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