2012-04-30 15 views
7

我正在寫一些單元測試,想知道是否有利於嘲笑Cache,如果是的話,如何?Mocking System.Web.Caching.Cache - 模擬或檢查null?

目前在我的測試中,我嘲諷了HttpContextBase和自定義HttpContextFactory包裹它:

var mockedHttpContextBase = new Mock<HttpContextBase>(); 

IHttpContextFactory httpContextFactory = new HttpContextFactory 
{ 
    Current = mockedHttpContextBase.Object 
}; 

,當我的代碼消耗的IHttpContextFactory我檢查,如果緩存是用它做任何事情之前空。

var cache = _httpContextFactory.Current.Cache; 

Func<SomeReturnType> doSomeWork =() => _foo.someMethodIExecute(param1,param2); 

return cache != null ? cache.GetOrStore("doSomeWorkCacheKey",doSomeWork, 900) 
        : doSomeWork.Invoke(); 

是否正確,檢查高速緩存每次使用它,或者你也會嘲笑緩存測試,以便它在運行單元測試時不爲空時被空也是這樣嗎?

回答

3

如果你的代碼假定緩存可以null和訪問之前進行檢查(像現在一樣),你需要爲每個緩存訪問兩個單元測試:

  • 緩存中存在和產品存儲和檢索(檢查GetOrStore調用)
  • 緩存爲空,你根本斷言委託調用

如果這是常見的模式(空檢查),每次需要緩存依賴性時,我都建議將其封裝到Null Object Pattern中,並且只需使用NOP作爲可被嘲笑的依賴項即可。

編輯:緩存「嘲諷」的例子

var cache = new Cache(); 
// Add takes more parameters; fill whatever is necessary to make it work 
cache.Add("doSomeWorkCacheKey", doSomeWork, ...); 
var mockedHttpContextBase = new Mock<HttpContextBase>(); 
// tell your mock to return pre-configured cache 
mockedHttpContextBase.Setup(m => m.Cache).Returns(cache); 

IHttpContextFactory httpContextFactory = new HttpContextFactory 
{ 
    Current = mockedHttpContextBase.Object 
}; 
+0

謝謝吉米。關於第1點,你將如何編寫一個依賴於現有緩存的測試?你如何在這種情況下嘲笑緩存來執行測試? –

+0

@JamieDixon:你不能真正模擬'Cache',因爲它是密封的;您必須使用真正的「Cache」實現對其進行預配置,並在請求時讓您的'HttpContextBase'模擬返回預配置的緩存。我爲我的帖子添加了示例。 –

+0

再次感謝吉米。我感謝你的時間和幫助。我在進行更多搜索後自己添加了一個答案。我似乎使用'HttpRuntime.Cache'更合適,因爲它會實例化它需要的所有東西,因爲如果一切都沒有配置,System.Web.Caching.Cache'會拋出'NullReferenceExeption'。 –

13

有點搜索它的後似乎寫我的單元測試時,我可以使用HttpRuntime.Cache而不是System.Web.Caching.Cache

這樣的:

var mockedHttpContextBase = new Mock<HttpContextBase>(); mockedHttpContextBase.Setup(m => m.Cache).Returns(HttpRuntime.Cache);

緩存不應該null(這將是一個合適的異常,如果確實如此),所以我可以刪除空引用從我的代碼檢查。

+0

良好的舉措避開unMoq'able封閉的System.Web.Caching.Cache與HttpRuntime.Cache – BozoJoe

+0

這不適合我,因爲我的測試是異步的。因此,'HttpRuntime.Cache'共享狀態,而不是每個測試。它在單獨運行測試時工作。 –

+0

要清楚 - 在這種情況下,您不要實例化緩存。在使用模擬版本之前,只需將您的項目添加到HttpRuntime.Cache。(HttpRuntime.Cache.Add(cacheKey,sampleUser,null,DateTime.Now.AddHours(2),Cache.NoSlidingExpiration,CacheItemPriority.Normal,null); var context = new Mock (); context.Setup(x => x.Cache).Returns(HttpRuntime.Cache);' – Lavamantis