2012-04-30 9 views
7

私は単体テストを書いており、Cacheを模擬することが有利かどうか疑問に思っています。Mocking System.Web.Caching.Cache - モックを確認するかヌルをチェックしますか?

は現在、私のテストでは、私はHttpContextBaseをからかってるとカスタムHttpContextFactoryでラップ:

var mockedHttpContextBase = new Mock<HttpContextBase>(); 

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

と私のコードは、キャッシュがそれで何かを行う前にnullの場合、私はチェックIHttpContextFactoryを消費するとき。

var cache = _httpContextFactory.Current.Cache; 

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

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

それが正しい、私はそれを使用するか、あなたのユニットテストを実行するとき、それがnullではないように、あなたはテストでも、キャッシュをあざけるだろうたびに、このようなヌルされたキャッシュをチェックしますか?

答えて

3

あなたのコードはキャッシュがnull可能と仮定し、(それが今ように)、あなたは各キャッシュアクセスための2つのユニットテストを持っている必要があり、それをアクセスする前にチェックを実行した場合:

  • キャッシュが存在し、アイテムがあります、
  • キャッシュがnullで、これは一般的なパターン(ヌルチェック)である場合は、単純に、デリゲートの呼び出し

をアサート(GetOrStoreコールをチェックする)保存し、検索キャッシュの依存関係が必要なたびに2つのテストを行う代わりに、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'実装を使用してそれを事前に設定し、' HttpContextBase'モックがリクエストされたときにあらかじめ設定されたキャッシュを返さなければなりません。私は私のポストに例を追加しました。 –

+0

もう一度ジミー。私はあなたの時間と助けに感謝します。私はより多くの検索をした後、自分で答えを加えました。 'HttpRuntime.Cache'を使うとより適切です。なぜなら、System.Web.Caching.Cache'がすべてが設定されていない場合に' NullReferenceExeption'を送出する場所で動作する必要があるすべてのインスタンスを生成するからです。 –

13

それを検索するのビットの後には、私のユニットテストを書くとき、私はSystem.Web.Caching.Cacheの代わりにHttpRuntime.Cacheを使用することができるようです。

このようなこと:

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

キャッシュがnullは(それがあった場合、それは適切な例外になる)ので、私は自分のコードからチェックnull参照を削除することができてはいけません。

+0

HttpRuntime.Cacheを使用してunMoq'able密封System.Web.Caching.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 =新しいモック(); context.Setup(x => x.Cache).Returns(HttpRuntime.Cache); ' – Lavamantis

関連する問題