---
generated_at: 2026-01-30 10:30:00
metrics:
  claims_total: 115
  claims_with_evidence: 112
  claims_without_evidence: 3
confidence_derived: 0.97
---

# 根拠レポート：Microsoft.Extensions.Caching.Memory 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.97**
  - 根拠あり：112 / 115、根拠なし：3
- 優先レビュー（高）
  1. **UT-MCM-113（ScanForExpiredItems）**：内部メソッドのため直接テスト不可能な可能性
  2. **UT-MCM-114（SetEntry状態遷移）**：internalメソッドの動作確認が必要
  3. **UT-MCM-115（CoherentState）**：privateクラスのため直接テスト不可能

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。

- E-01: `src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs`
- E-02: `src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs`
- E-03: `src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.CacheEntryTokens.cs`
- E-04: `src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCacheOptions.cs`
- E-05: `src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryDistributedCache.cs`
- E-06: `src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryDistributedCacheOptions.cs`
- E-07: `src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCacheServiceCollectionExtensions.cs`

## 3) Claims と根拠の対応（レビューの主戦場）

### MemoryCache クラス（UT-MCM-001 〜 UT-MCM-035）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | コンストラクタでnullチェックが行われる | E-01 (L52-53) ArgumentNullException.ThrowIfNull | ○ |
| C-02 | CreateEntryでnullキーチェックが行われる | E-01 (L102) ArgumentNullException.ThrowIfNull(key) | ○ |
| C-03 | Dispose後にCheckDisposedで例外スロー | E-01 (L687-696) CheckDisposed実装確認 | ○ |
| C-04 | TryGetValueでnullキーチェックが行われる | E-01 (L207) ArgumentNullException.ThrowIfNull(key) | ○ |
| C-05 | TryGetValueでキャッシュヒット/ミスが記録される | E-01 (L286-313) _stats更新ロジック | ○ |
| C-06 | Removeでnullキーチェックが行われる | E-01 (L321) ArgumentNullException.ThrowIfNull(key) | ○ |
| C-07 | Remove時にEvictionCallbackが呼び出される | E-01 (L334-335) SetExpired + InvokeEvictionCallbacks | ○ |
| C-08 | Clearで全エントリにEvictionCallbackが呼び出される | E-01 (L349-353) foreach + InvokeEvictionCallbacks | ○ |
| C-09 | Countプロパティがエントリ数を返す | E-01 (L80) _coherentState.Count | ○ |
| C-10 | Keysプロパティが全キーを列挙 | E-01 (L85-86) GetAllKeys() | ○ |
| C-11 | GetCurrentStatisticsがTrackStatistics依存 | E-01 (L360-375) _allStats nullチェック | ○ |
| C-12 | Compactが優先度に基づいて削除 | E-01 (L602-618) Priority別リスト作成 | ○ |
| C-13 | NeverRemove優先度は削除されない | E-01 (L613-614) case CacheItemPriority.NeverRemove: break | ○ |
| C-14 | LRUアルゴリズムで削除順序決定 | E-01 (L648) LastAccessed.CompareTo | ○ |
| C-15 | Dispose後の操作でObjectDisposedException | E-01 (L695) throw new ObjectDisposedException | ○ |
| C-16 | SizeLimit設定時にSize必須 | E-01 (L115-118) HasSizeLimit && entry.Size < 0チェック | ○ |
| C-17 | 同一キー上書き時にReplacedイベント | E-01 (L140) priorEntry.SetExpired(EvictionReason.Replaced) | ○ |
| C-18 | 容量超過時にOvercapacityCompactionトリガー | E-01 (L192-193, L524-544) TriggerOvercapacityCompaction | ○ |
| C-19 | ReadOnlySpan<char>オーバーロード（.NET向け） | E-01 (L224-261) #if NET条件付きコンパイル | ○ |
| C-20 | 期限切れエントリはTryGetValueで削除される | E-01 (L298-300) CheckExpired後のRemoveEntry | ○ |

### CacheEntry クラス（UT-MCM-036 〜 UT-MCM-066）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-21 | コンストラクタでnullチェック | E-02 (L40-41) ArgumentNullException.ThrowIfNull | ○ |
| C-22 | Valueの設定/取得が可能 | E-02 (L175-183) _value, _isValueSet | ○ |
| C-23 | AbsoluteExpiration設定/取得 | E-02 (L66-94) ICacheEntry.AbsoluteExpiration | ○ |
| C-24 | AbsoluteExpirationRelativeToNow正値のみ | E-02 (L106-112) ArgumentOutOfRangeException | ○ |
| C-25 | SlidingExpiration正値のみ | E-02 (L127-133) ArgumentOutOfRangeException | ○ |
| C-26 | Size非負値のみ | E-02 (L164-166) ArgumentOutOfRangeException | ○ |
| C-27 | Priority設定/取得 | E-02 (L155) CacheItemPriority cast | ○ |
| C-28 | デフォルトPriorityがNormal | E-02 (L34) _priority = (byte)CacheItemPriority.Normal | ○ |
| C-29 | ExpirationTokens追加可能 | E-02 (L143) GetOrCreateTokens().ExpirationTokens | ○ |
| C-30 | PostEvictionCallbacks追加可能 | E-02 (L149) GetOrCreateTokens().PostEvictionCallbacks | ○ |
| C-31 | Disposeでキャッシュにコミット | E-02 (L189-204) _cache.SetEntry(this) | ○ |
| C-32 | 値未設定時はコミットされない | E-02 (L199, L214) _isValueSetチェック | ○ |
| C-33 | CheckExpiredが時間/トークン確認 | E-02 (L234-237) _isExpired, CheckForExpiredTime, CheckForExpiredTokens | ○ |
| C-34 | SetExpiredでEvictionReason設定 | E-02 (L239-247) EvictionReason設定ロジック | ○ |
| C-35 | InvokeEvictionCallbacksで非同期呼び出し | E-03 (L105-111) Task.Factory.StartNew | ○ |
| C-36 | コールバック例外がキャッチされログ出力 | E-03 (L128-136) try-catch + LogError | ○ |
| C-37 | PropagateOptionsToCurrentで親に伝播 | E-02 (L293-309) 親エントリへのAbsoluteExpiration/Token伝播 | ○ |

### CacheEntryTokens クラス（UT-MCM-109 〜 UT-MCM-112）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-38 | AttachTokensでコールバック登録 | E-03 (L27-46) RegisterChangeCallback | ○ |
| C-39 | DetachTokensで登録解除 | E-03 (L83-103) registrations.Dispose() | ○ |
| C-40 | CheckForExpiredTokensでHasChanged確認 | E-03 (L48-64) expiredToken.HasChanged | ○ |
| C-41 | PropagateTokensで親にトークン追加 | E-03 (L68-81) parentTokens.ExpirationTokens.AddRange | ○ |

### MemoryCacheOptions クラス（UT-MCM-067 〜 UT-MCM-079）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-42 | SizeLimit非負値のみ | E-04 (L49-51) ArgumentOutOfRangeException | ○ |
| C-43 | SizeLimit null設定可 | E-04 (L54) _sizeLimit = value ?? NotSet | ○ |
| C-44 | CompactionPercentage 0-1範囲のみ | E-04 (L73-76) ArgumentOutOfRangeException | ○ |
| C-45 | ExpirationScanFrequencyデフォルト1分 | E-04 (L29) TimeSpan.FromMinutes(1) | ○ |
| C-46 | TrackStatistics設定可 | E-04 (L99) public bool TrackStatistics | ○ |
| C-47 | TrackLinkedCacheEntries設定可 | E-04 (L90) public bool TrackLinkedCacheEntries | ○ |
| C-48 | Clock設定可 | E-04 (L24) public ISystemClock? Clock | ○ |

### MemoryDistributedCache クラス（UT-MCM-080 〜 UT-MCM-098）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-49 | コンストラクタでnullチェック | E-05 (L35-36) ArgumentNullException.ThrowIfNull | ○ |
| C-50 | Getでnullキーチェック | E-05 (L48) ArgumentNullException.ThrowIfNull(key) | ○ |
| C-51 | Get戻り値がbyte[] | E-05 (L50-51) (byte[]?)value | ○ |
| C-52 | GetAsync非同期実装 | E-05 (L60-65) Task.FromResult(Get(key)) | ○ |
| C-53 | Setでnullチェック (key, value, options) | E-05 (L75-77) 3つのArgumentNullException.ThrowIfNull | ○ |
| C-54 | Set時にSizeがvalue.Lengthに設定 | E-05 (L83) entry.Size = value.Length | ○ |
| C-55 | SetAsyncで同期Set呼び出し | E-05 (L101) Set(key, value, options) | ○ |
| C-56 | RefreshでTryGetValue呼び出し | E-05 (L113) _memCache.TryGetValue(key, out _) | ○ |
| C-57 | Removeで_memCache.Remove呼び出し | E-05 (L138) _memCache.Remove(key) | ○ |

### MemoryDistributedCacheOptions クラス（UT-MCM-099）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-58 | デフォルトSizeLimitが200MB | E-06 (L18) SizeLimit = 200 * 1024 * 1024 | ○ |

### MemoryCacheServiceCollectionExtensions クラス（UT-MCM-100 〜 UT-MCM-107）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-59 | AddMemoryCacheでnullチェック | E-07 (L24) ArgumentNullException.ThrowIfNull(services) | ○ |
| C-60 | AddMemoryCacheでIMemoryCacheシングルトン登録 | E-07 (L27) ServiceDescriptor.Singleton<IMemoryCache, MemoryCache> | ○ |
| C-61 | AddMemoryCache(setupAction)でnullチェック | E-07 (L43-44) 2つのArgumentNullException.ThrowIfNull | ○ |
| C-62 | AddDistributedMemoryCacheでnullチェック | E-07 (L68) ArgumentNullException.ThrowIfNull(services) | ○ |
| C-63 | AddDistributedMemoryCacheでIDistributedCacheシングルトン登録 | E-07 (L71) ServiceDescriptor.Singleton<IDistributedCache, MemoryDistributedCache> | ○ |
| C-64 | AddDistributedMemoryCache(setupAction)でnullチェック | E-07 (L95-96) 2つのArgumentNullException.ThrowIfNull | ○ |

### 内部実装テスト（UT-MCM-108, UT-MCM-113 〜 UT-MCM-115）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-65 | 文字列と非文字列キーの分離 | E-01 (L717-721) _stringEntries, _nonStringEntries | ○ |
| C-66 | ScanForExpiredItemsでバックグラウンドスキャン | E-01 (L464-477) privateメソッド | △ |
| C-67 | 期限切れエントリ追加時の即時Eviction | E-01 (L143-149) CheckExpired後のInvokeEvictionCallbacks | ○ |
| C-68 | CoherentStateの内部キー管理 | E-01 (L714-825) privateクラス | △ |

## 4) 不足情報（Unknown / Missing）

- **ScanForExpiredItems（UT-MCM-113）**: privateメソッドのため、直接的な単体テストは困難。統合テストまたはreflectionによるテストが必要
  - 候補：既存テストの `TimeExpirationTests.cs` / バックグラウンドタスク経由での検証
- **SetEntry状態遷移（UT-MCM-114）**: internalメソッドのため、InternalsVisibleToを使用したテストプロジェクトでのテストが必要
  - 候補：`tests/` 配下の既存テストパターン参照
- **CoherentState（UT-MCM-115）**: privateネストクラスのため、直接テスト不可。MemoryCacheのpublicメソッド経由での間接的な検証が必要
  - 候補：Countプロパティ / Keysプロパティを通じた検証

## 5) リスクフラグ（レビュー観点）

| リスクレベル | 項目 | 理由 |
|---|---|---|
| 1: 中リスク | 並行処理テスト | MemoryCacheは並行アクセスを想定しているが、テストケースに明示的な並行テストがない |
| 1: 中リスク | メモリリーク検証 | WeakReference使用部分のメモリリーク検証が必要 |
| 0: 低リスク | パフォーマンステスト | 大量エントリ時の性能検証は単体テストの範囲外 |
| 1: 中リスク | .NET Framework互換性 | #if NET条件付きコンパイル部分のクロスプラットフォームテスト |

## 6) レビュアーチェックリスト（最小）

- [ ] 全てのpublicメソッドに対するテストケースが存在するか確認
- [ ] ArgumentNullExceptionのテストが全null許容パラメータに対して存在するか確認
- [ ] 境界値テスト（0、負値、最大値）が適切に設計されているか確認
- [ ] EvictionCallbackの呼び出しタイミングが全EvictionReasonでカバーされているか確認
- [ ] TrackStatistics/TrackLinkedCacheEntriesの有効/無効両方のパスがテストされているか確認
- [ ] SizeLimitの有無による分岐が網羅されているか確認
- [ ] 非同期メソッド（GetAsync、SetAsync等）のテストが同期版と同等のカバレッジか確認
- [ ] internalメソッド（SetEntry、EntryExpired等）のテスト戦略を確認
