1 // ================================================================================================
3 // MemoryCacheのテストクラスソース。</summary>
5 // <copyright file="MemoryCacheTest.cs" company="honeplusのメモ帳">
6 // Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
9 // ================================================================================================
11 namespace Honememo.Models
14 using System.Collections.Generic;
15 using System.Threading;
16 using System.Threading.Tasks;
17 using NUnit.Framework;
20 /// <see cref="MemoryCache<TKey, TValue>"/>のテストクラスです。
23 internal class MemoryCacheTest
28 /// <see cref="MemoryCache<TKey, TValue>.Capacity"/>プロパティテストケース(正常系)。
31 public void TestCapacity()
33 MemoryCache<string, string> cache = new MemoryCache<string, string>();
35 Assert.AreEqual(1, cache.Capacity);
37 Assert.AreEqual(100, cache.Capacity);
38 cache.Capacity = int.MaxValue;
39 Assert.AreEqual(int.MaxValue, cache.Capacity);
43 /// <see cref="MemoryCache<TKey, TValue>.Capacity"/>プロパティテストケース(0以下の値)。
46 [ExpectedException(typeof(ArgumentException))]
47 public void TestCapacityZero()
49 new MemoryCache<string, string>().Capacity = 0;
57 /// インデクサーテストケース(正常系)。
60 public void TestThis()
62 // ※ 以下古いほうから削除の確認のために、登録時に毎回ウェイトを入れる
63 MemoryCache<string, string> cache = new MemoryCache<string, string>();
66 cache["testkey"] = "testvalue";
67 Assert.AreEqual("testvalue", cache["testkey"]);
68 Assert.IsFalse(cache.ContainsKey("testkey2"));
69 Assert.IsFalse(cache.ContainsKey("testkey3"));
72 cache["testkey2"] = "testvalue2";
73 Assert.AreEqual("testvalue", cache["testkey"]);
74 Assert.AreEqual("testvalue2", cache["testkey2"]);
75 Assert.IsFalse(cache.ContainsKey("testkey3"));
79 cache["testkey2"] = "testvalue2-2";
80 Assert.AreEqual("testvalue2-2", cache["testkey2"]);
84 cache["testkey3"] = null;
85 Assert.IsTrue(cache.ContainsKey("testkey3"));
86 Assert.IsNull(cache["testkey3"]);
89 // キャッシュが100件を超えると最後にgetされたのが古い方から10件削除される
90 for (int i = 4; i <= 100; i++)
92 cache[i.ToString()] = i.ToString();
97 Assert.IsTrue(cache.ContainsKey("testkey"));
98 Assert.IsTrue(cache.ContainsKey("testkey2"));
99 Assert.IsTrue(cache.ContainsKey("testkey3"));
100 Assert.IsTrue(cache.ContainsKey("4"));
101 Assert.IsTrue(cache.ContainsKey("11"));
102 Assert.IsTrue(cache.ContainsKey("12"));
103 Assert.IsTrue(cache.ContainsKey("100"));
104 Assert.IsFalse(cache.ContainsKey("testkey101"));
107 Assert.AreEqual("testvalue2-2", cache["testkey2"]);
108 cache["testkey101"] = "testvalue101";
110 // アクセスが古い方から10件が削除される
111 Assert.IsFalse(cache.ContainsKey("testkey"));
112 Assert.IsTrue(cache.ContainsKey("testkey2"));
113 Assert.IsFalse(cache.ContainsKey("testkey3"));
114 Assert.IsFalse(cache.ContainsKey("4"));
115 Assert.IsFalse(cache.ContainsKey("11"));
116 Assert.IsTrue(cache.ContainsKey("12"));
117 Assert.IsTrue(cache.ContainsKey("100"));
118 Assert.IsTrue(cache.ContainsKey("testkey101"));
119 Assert.AreEqual("testvalue2-2", cache["testkey2"]);
120 Assert.AreEqual("12", cache["12"]);
121 Assert.AreEqual("testvalue101", cache["testkey101"]);
125 /// インデクサーテストケース(getでnull)。
128 [ExpectedException(typeof(ArgumentNullException))]
129 public void TestThisGetNull()
131 string dummy = new MemoryCache<string, string>()[null];
135 /// インデクサーテストケース(getで値無し)。
138 [ExpectedException(typeof(KeyNotFoundException))]
139 public void TestThisGetEmpty()
141 string dummy = new MemoryCache<string, string>()["ignore key"];
145 /// インデクサーテストケース(setでnull)。
148 [ExpectedException(typeof(ArgumentNullException))]
149 public void TestThisSetNull()
151 new MemoryCache<string, string>()[null] = "test";
156 #region IDictionaryインタフェースにあわせたメソッド
159 /// <see cref="MemoryCache<TKey, TValue>.Add"/>メソッドテストケース(正常系)。
162 public void TestAdd()
164 // ※ 2012年2月現在、重複チェック以外はインデクサーと同じなので割愛
165 MemoryCache<string, string> cache = new MemoryCache<string, string>();
167 cache.Add("testkey", "testvalue");
168 Assert.AreEqual("testvalue", cache["testkey"]);
169 Assert.IsFalse(cache.ContainsKey("testkey2"));
171 cache.Add("testkey2", "testvalue2");
172 Assert.AreEqual("testvalue", cache["testkey"]);
173 Assert.AreEqual("testvalue2", cache["testkey2"]);
177 /// <see cref="MemoryCache<TKey, TValue>.Add"/>メソッドテストケース(null)。
180 [ExpectedException(typeof(ArgumentNullException))]
181 public void TestAddNull()
183 new MemoryCache<string, string>().Add(null, "dummy");
187 /// <see cref="MemoryCache<TKey, TValue>.Add"/>メソッドテストケース(重複)。
190 [ExpectedException(typeof(ArgumentException))]
191 public void TestAddAlready()
194 MemoryCache<string, string> cache = new MemoryCache<string, string>();
195 cache["testkey"] = "testvalue";
196 cache.Add("testkey", "testvalue");
200 /// <see cref="MemoryCache<TKey, TValue>.ContainsKey"/>メソッドテストケース。
203 public void TestContainsKey()
205 MemoryCache<string, string> cache = new MemoryCache<string, string>();
207 Assert.IsFalse(cache.ContainsKey("testkey"));
208 Assert.IsFalse(cache.ContainsKey("testkey2"));
210 cache["testkey"] = "testvalue";
211 Assert.IsTrue(cache.ContainsKey("testkey"));
212 Assert.IsFalse(cache.ContainsKey("testkey2"));
214 cache["testkey2"] = "testvalue2";
215 Assert.IsTrue(cache.ContainsKey("testkey"));
216 Assert.IsTrue(cache.ContainsKey("testkey2"));
220 /// <see cref="MemoryCache<TKey, TValue>.ContainsKey"/>メソッドテストケース(null)。
223 [ExpectedException(typeof(ArgumentNullException))]
224 public void TestContainsKeyNull()
226 new MemoryCache<string, string>().ContainsKey(null);
230 /// <see cref="MemoryCache<TKey, TValue>.Remove"/>メソッドテストケース。
233 public void TestRemove()
236 MemoryCache<string, string> cache = new MemoryCache<string, string>();
237 cache["testkey"] = "testvalue";
238 cache["testkey2"] = "testvalue2";
239 Assert.IsTrue(cache.ContainsKey("testkey"));
240 Assert.IsTrue(cache.ContainsKey("testkey2"));
241 Assert.AreEqual("testvalue", cache.Get("testkey"));
242 Assert.AreEqual("testvalue2", cache.Get("testkey2"));
244 Assert.IsTrue(cache.Remove("testkey"));
245 Assert.IsFalse(cache.ContainsKey("testkey"));
246 Assert.IsTrue(cache.ContainsKey("testkey2"));
248 Assert.IsTrue(cache.Remove("testkey2"));
249 Assert.IsFalse(cache.ContainsKey("testkey"));
250 Assert.IsFalse(cache.ContainsKey("testkey2"));
253 Assert.IsFalse(cache.Remove("testkey"));
257 /// <see cref="MemoryCache<TKey, TValue>.Remove"/>メソッドテストケース(null)。
260 [ExpectedException(typeof(ArgumentNullException))]
261 public void TestRemoveNull()
263 new MemoryCache<string, string>().Remove(null);
267 /// <see cref="MemoryCache<TKey, TValue>.TryGetValue"/>メソッドテストケース(正常系)。
270 public void TestTryGetValue()
272 // ※ 2012年2月現在、例外処理以外についてはインデクサーやGetと同じなので割愛
273 MemoryCache<string, string> cache = new MemoryCache<string, string>();
276 Assert.IsFalse(cache.TryGetValue("testkey", out result));
278 cache["testkey"] = "testvalue";
279 Assert.IsTrue(cache.TryGetValue("testkey", out result));
280 Assert.AreEqual("testvalue", cache.Get("testkey"));
284 /// <see cref="MemoryCache<TKey, TValue>.TryGetValue"/>メソッドテストケース(null)。
287 [ExpectedException(typeof(ArgumentNullException))]
288 public void TestTryGetValueNull()
291 new MemoryCache<string, string>().TryGetValue(null, out dummy);
295 /// <see cref="MemoryCache<TKey, TValue>.Clear"/>メソッドテストケース。
298 public void TestClear()
301 MemoryCache<string, string> cache = new MemoryCache<string, string>();
302 cache["testkey"] = "testvalue";
303 cache["testkey2"] = "testvalue2";
304 Assert.IsTrue(cache.ContainsKey("testkey"));
305 Assert.IsTrue(cache.ContainsKey("testkey2"));
306 Assert.AreEqual("testvalue", cache.Get("testkey"));
307 Assert.AreEqual("testvalue2", cache.Get("testkey2"));
310 Assert.IsFalse(cache.ContainsKey("testkey"));
311 Assert.IsFalse(cache.ContainsKey("testkey2"));
316 #region 独自のメソッドテストケース
319 /// <see cref="MemoryCache<TKey, TValue>.Get"/>メソッドテストケース(正常系)。
322 public void TestGet()
324 // ※ 2012年2月現在インデクサーを呼んでいるだけなのでテスト割愛
325 MemoryCache<string, string> cache = new MemoryCache<string, string>();
326 cache["testkey"] = "testvalue";
327 Assert.AreEqual("testvalue", cache.Get("testkey"));
331 /// <see cref="MemoryCache<TKey, TValue>.Get"/>メソッドテストケース(null)。
334 [ExpectedException(typeof(ArgumentNullException))]
335 public void TestGetNull()
337 new MemoryCache<string, string>().Get(null);
341 /// <see cref="MemoryCache<TKey, TValue>.Get"/>メソッドテストケース(値無し)。
344 [ExpectedException(typeof(KeyNotFoundException))]
345 public void TestGetEmpty()
347 new MemoryCache<string, string>().Get("ignore key");
351 /// <see cref="MemoryCache<TKey, TValue>.GetAndAddIfEmpty"/>メソッドテストケース(正常系)。
354 public void TestGetAndAddIfEmpty()
356 MemoryCache<string, string> cache = new MemoryCache<string, string>();
358 // 値があればその値を、無ければファンクションが返す値を返す
359 cache["testkey"] = "testvalue";
360 Assert.AreEqual("testvalue", cache.GetAndAddIfEmpty("testkey", (string str) => "testvalue2"));
361 Assert.AreEqual("testvalue2", cache.GetAndAddIfEmpty("testkey2", (string str) => "testvalue2"));
362 Assert.AreEqual("testvalue2", cache.GetAndAddIfEmpty("testkey3", (string str) => "testvalue2"));
364 // ファンクションが返した値はキャッシュに登録される
365 Assert.AreEqual("testvalue2", cache["testkey2"]);
366 Assert.AreEqual("testvalue2", cache["testkey3"]);
369 Assert.IsNull(cache.GetAndAddIfEmpty("testkey4", (string str) => null));
370 Assert.IsTrue(cache.ContainsKey("testkey4"));
374 /// <see cref="MemoryCache<TKey, TValue>.GetAndAddIfEmpty"/>メソッドテストケース(null)。
377 [ExpectedException(typeof(ArgumentNullException))]
378 public void TestGetAndAddIfEmptyNull()
380 new MemoryCache<string, string>().GetAndAddIfEmpty(null, (string str) => "testvalue2");
390 [Test, Timeout(1500)]
391 public void TestMemoryCacheParallel()
393 // 並列実行でいくつかのメソッドを呼んで問題ないかを確認する
394 // ※ 結果などはあまり確認できないので、とりあえず変なエラーにならないことだけ
395 MemoryCache<int, string> cache = new MemoryCache<int, string>();
403 cache[key] = i.ToString();
405 if (cache.TryGetValue(key, out result))
407 // ※ 登録した直後でも、別スレッドからの登録でキャッシュがあふれて消えることもあるので
408 Assert.AreEqual(key, int.Parse(result) % 200);