2015-10-30 121 views
0

我试图单元测试一些代码,它从HttpContext.Current.Application中读取一个值,但由于它无法检索值而一直保持失败。使用HttpContext.Application进行单元测试

我试过创建自己的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; 
+0

您是否检查过其他人如何模拟HttpContext(https://www.bing.com/search?q=Unit+testing+with+HttpContext.Application)或考虑将该访问抽象为依赖关系? –

回答

1

Don't mock HttpContext !!!!他不喜欢被嘲笑!

相反,弄清楚你想实现什么功能,并设计一个抽象。这将允许您的代码更易于测试,因为它不与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<string,object> Application = new Dictionary<string,object>(); 
     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); 
    } 
} 

在生产代码你将使用实际的版本而不是假的。如果你决定使用别的东西来存储你的变量,这也允许你在不同的版本中换入和换出不同的版本。

+0

谢谢NKosi,这非常接近我最终做的。我欣赏这些解释! –