C# 如何在UnitTest asp.net中使用应用程序变量

C# 如何在UnitTest asp.net中使用应用程序变量,c#,asp.net,unit-testing,C#,Asp.net,Unit Testing,我有一个使用应用程序变量从外部文件获取信息的方法。由于单元测试中不使用应用程序变量,有没有办法从Global.asax文件中获取应用程序变量值并在测试中使用它们 这是我的测试方法: [TestMethod] public void TestGetCompanyList() { var accController = new AccSerController(); CInt cInt = new CInt(); cIn.Iss = "Other"; cIn.Tick

我有一个使用应用程序变量从外部文件获取信息的方法。由于单元测试中不使用应用程序变量,有没有办法从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);
}
[TestMethod]
public void TestGetCompanyList()
{
var accController=新的acccsercontroller();
CInt CInt=新的CInt();
cIn.Iss=“其他”;
cIn.Tick=“BK”;
var结果
=accController.Clist(cIn)作为IEnumerable;
Assert.IsNotNull(结果);
}

在我的一些测试中,我做了以下几点。虽然不理想,但它完成了任务

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

据我所知,有两种单元测试这种场景的方法

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

之前:

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,我不确定这是否是必须的。您可能应该能够以类似的方式创建它,以及您使用的其他变量。不管怎么说,这算是一种黑客行为,所以就这样对待它吧。您的控制器不应该知道
网络配置

//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;}
}
private static void RegisterServices(IKernel kernel)  
{
    kernel.Bind<ISiteConfiguration>().To<WebConfiguration>();
}
我用它来执行依赖注入,但是还有很多其他库。我将从我的答案中省略一些基本的Ninject设置,因为这里有。但下面的代码显示了如何在web应用程序中指定使用
WebConfiguration
来满足
ISiteConfiguration
的需要

//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;}
}
private static void RegisterServices(IKernel kernel)  
{
    kernel.Bind<ISiteConfiguration>().To<WebConfiguration>();
}
您也可以在单元测试中使用Ninject,但这里有一个更简单的演示,我们不使用它:

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

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

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