2015-10-30 161 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,這非常接近我最終做的。我欣賞這些解釋! –