使用HttpContext.Application进行unit testing

我正在尝试对从HttpContext.Current.Application中读取值的一些代码进行unit testing,但它仍然失败,因为它无法检索该值。

我已经尝试创建自己的HttpContext ,将HttpContext.Current设置为它,然后向其中写入值,但它似乎不存储新值。

代码引用HttpContext.Current.Application

 public static void UpdateApplicationVariable(string keyToUpdate, object toSave) { HttpContext.Current.Application.Lock(); HttpContext.Current.Application[keyToUpdate] = toSave; HttpContext.Current.Application.UnLock(); } public static object GetApplicationVariable(string keyToReturn) { return HttpContext.Current.Application[keyToReturn]; } 

设置代码

 HttpContext.Current = new HttpContext( new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null) ); UpdateApplicationVariable("GeneralSettings", new GeneralSettings() { NumberDecimalPlaces = 2 }); //settings is null GeneralSettings settings = GetApplicationVariable("GeneralSettings") as GeneralSettings; 

不要嘲笑HttpContext !!!! 他不喜欢被嘲笑!

而是弄清楚你想要实现的function是什么,并围绕它设计一个抽象。 这将允许您的代码更加可测试,因为它与HttpContext没有紧密耦合。

 public interface IApplicationSettings { object this[string key] { get; set; } } 

在您的代码中引用HttpContext.Current.Application可以更改…

 public static class SomeUtilityClass { public static IApplicationSettings Application {get;set;} public static void UpdateApplicationVariable(string keyToUpdate, object toSave) { Application[keyToUpdate] = toSave; } public static object GetApplicationVariable(string keyToReturn) { return Application[keyToReturn]; } } 

具体版本将具有访问HttpContext所需的实际代码。 就像是…

 public class ConcreteApplicationSettings : IApplicationSettings { public string this[string keyToReturn] { get { return HttpContext.Current.Application[keyToReturn]; } set { HttpContext.Current.Application.Lock(); HttpContext.Current.Application[keyToUpdate] = value; HttpContext.Current.Application.UnLock(); } } } 

现在在您的代码设置中进行测试,您可以通过使用抽象的模拟,伪造或存根版本完全放弃HttpContext …

 [TestClass] public class ApplicationVariablesTests { public class FakeApplicationSettings : IApplicationSettings { Dictionary Application = new Dictionary(); public string this[string keyToReturn] { get { return Application[keyToReturn]; } set { Application[keyToUpdate] = value; } } } [TestMethod] public void Should_Update_General_Settings() { //Arrange SomeUtilityClass.Application = new FakeApplicationSettings(); SomeUtilityClass.UpdateApplicationVariable("GeneralSettings", new GeneralSettings() { NumberDecimalPlaces = 2 }); //Act GeneralSettings settings = SomeUtilityClass.GetApplicationVariable("GeneralSettings") as GeneralSettings; //Assert Assert.IsNotNull(settings); Assert.AreEqual(2, settings.NumberDecimalPlaces); } } 

在生产代码中,您将使用实际版本而不是假的。 如果您决定使用其他内容来存储变量,这也允许您在fusture中交换进出不同的版本。