【问题标题】:How to use application variables in UnitTest asp.net如何在 UnitTest asp.net 中使用应用程序变量
【发布时间】:2016-12-28 20:58:19
【问题描述】:

我有一个使用应用程序变量从外部文件获取信息的方法。由于单元测试中不使用应用程序变量,有没有办法从我的 Global.asax 文件中获取应用程序变量值并能够在测试中使用它们?

这是我的测试方法:

[TestMethod]
public void TestGetCompanyList()
{
    var accController = new AccSerController();
    CInt cInt = new CInt();
    cIn.Iss = "Other";
    cIn.Tick = "BK";
    var result
      = accController.Clist(cIn) as IEnumerable<CList>;
    Assert.IsNotNull(result);
}

【问题讨论】:

  • 我看到了第一个链接,但不能真正跟进(我是新手)。现在看第二个链接。
  • 你是如何加载应用程序变量的?
  • 不要为此使用应用程序变量。使用存储库模式。您的网页/控制器不需要知道存储库的详细信息,只需了解界面即可。然后,您可以为单元测试使用不同的存储库实现。
  • @mason 什么是存储库模式?这是我第一次听说。我在哪里可以了解更多信息。

标签: c# asp.net unit-testing


【解决方案1】:

使用repository pattern。你的控制器不应该知道WebConfiguration

//This defines the stuff that your controller needs (that your repository should contain)
public interface ISiteConfiguration
{
    string Setting1 {get; set;}
}

//Use this in your site. Pull configuration from external file
public class WebConfiguration : ISiteConfiguration
{
    public string Setting1 {get; set;}

    public WebConfiguration()
    {
        //Read info from external file here and store in Setting1
        Setting1 = File.ReadAllText(HttpContext.Current.Server.MapPath("~/config.txt"));
    }
}

//Use this in your unit tests. Manually specify Setting1 as part of "Arrange" step in unit test. You can then use this to test the controller.
public class TestConfiguration : ISiteConfiguration
{
    public string Setting1 {get; set;}
}

我正在使用Ninject 执行依赖注入,但还有很多其他库。我将从我的答案中省略一些基本的 Ninject 设置,因为那里有 plenty of resources。但下面的代码显示了如何在 Web 应用程序中指定使用 WebConfiguration 来满足 ISiteConfiguration 的需求。

private static void RegisterServices(IKernel kernel)  
{
    kernel.Bind<ISiteConfiguration>().To<WebConfiguration>();
}

这就是魔法发生的地方。当您的控制器实例在您的 Web 应用程序中创建时,Ninject 将查看构造函数并看到它正在请求ISiteConfiguration。在您的 Ninject 配置中,您告诉它在需要 ISiteConfiguration 时使用 WebConfiguration。因此,Ninject 将创建一个新的 WebConfiguration 实例并将其提供(注入)给您的控制器。

public class AccountServiceController
{
    ISiteConfiguration Config {get; set;}

    //This is called constructor injection
    public AccountServiceController(ISiteConfiguration config)
    {
        Config = config;
    }

    public ActionResult Index()
    {
        //Now you can use Config without needing to know about ISiteConfiguration's implementation details
        //Get settings from Config instead of Application
    } 
}

您也可以在单元测试中使用 Ninject,但这里有一个更简单的演示,我们没有使用它:

[TestMethod]
public void TestGetCompanyList()
{
    //Arrange
    var config = new TestConfiguration(){ Setting1 = "mysetting" };
    var accountController = new AccountServiceController(config);
}

所有这些的结果是您可以轻松地使用控制器的操作方法进行单元测试,因为您可以使用任何您想要的ISiteConfiguration 实现。

【讨论】:

    【解决方案2】:

    我在一些测试中完成了以下操作。不理想,但它可以完成工作。

    if (System.Web.HttpContext.Current != null)
    {
         //   Fill your application variable
    }
    else
    {
         //   Get your data from somewhere else                    
    }
    

    【讨论】:

      【解决方案3】:

      据我所知,有两种方法可以对此类场景进行单元测试。

      第一个基于将控制器功能拆分为两个:一个是控制器功能本身,另一个是实现逻辑(例如:这是您测试的那个)。示例:

      之前:

      public void MyControllerFunction()
      {
          var x = Context["variable"];
          do-something-with-x;
      }
      

      之后:

      public void MyControllerFunction()
      {
          var x = Context["variable"];
          MyControllerLogic(x);
      }
      
      internal void MyControllerLogic(object x)
      {
          do-something-with-x;
      }
      

      然后你在单元测试中测试MyControllerLogic() 函数而不是MyControllerFunction()

      另一种方法是在调用单元测试之前创建代理上下文。

      例子:

      var controller = new MyController();
      controller.Request = new HttpRequestMessage();
      controller.Configuration = new HttpConfiguration();
      controller.Request.Content = new StringContent("{ x: 21 }",
           Encoding.Unicode);
      controller.Request.Content.Headers.ContentType.MediaType =
           "application/json";
      

      请注意,我没有在第二个示例中创建 HttpContext,我不确定这是否是必需的。您可能应该能够以类似的方式以及您使用的其他变量来创建它。无论如何,这有点像黑客,所以这样对待它

      【讨论】:

        猜你喜欢
        • 2018-09-22
        • 1970-01-01
        • 2019-06-24
        • 2012-10-27
        • 2019-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多