導入
テスト駆動開発(TDD)はすでに学びました。実務では「DBや外部API(=遅い・不安定)」に依存するクラスをテストしたい場面が多くあります。Moqは、インターフェースの**偽物(モック)**をその場で作り、「このメソッドが呼ばれたらこの値を返す」と振る舞いを指定して、対象クラスだけを純粋にテストできるようにします。
図解
flowchart LR
TEST["テスト"] -->|本物の代わりに注入| MOCK["Mock<IUserRepository><br/>Setup で戻り値を固定"]
MOCK --> SUT["UserService(テスト対象)"]
SUT --> TEST
TEST -->|Verify| MOCK
進め方
- スターター
121-moq/starter.zipを展開し、MoqLesson.slnを開く(xUnit+Moq導入済み) - テストのTODO(Setup / Verify)を埋める
- テストエクスプローラーで緑になることを確認する
学ぶこと
using Moq;
using Xunit;
[Fact]
public void 存在するユーザーは名前を返す()
{
// 1) 偽物のリポジトリを作り、振る舞いを指定
var repo = new Mock<IUserRepository>();
repo.Setup(r => r.FindById(1)).Returns(new User(1, "Taro"));
// 2) 偽物を注入してテスト対象を動かす
var service = new UserService(repo.Object);
string name = service.GetUserName(1);
// 3) 結果と「呼ばれ方」を検証
Assert.Equal("Taro", name);
repo.Verify(r => r.FindById(1), Times.Once); // 1回だけ呼ばれたはず
}
new Mock<IインターフェースT>()で偽物を作り、.Objectで本物として渡せるSetup(...).Returns(...)で「この呼び出しにはこの戻り値」を固定するVerify(..., Times.Once)で「期待どおり呼ばれたか」を検証できる- モックのおかげでDBやAPIに触れずに済み、テストが速く・安定・独立になる(DIが前提)
期待される出力
テスト実行: 2件中2件成功
まとめ
- Moqはインターフェースの偽物を作り、戻り値と呼ばれ方を制御する
Setupで振る舞い指定、Verifyで呼び出し検証- 遅い・不安定な依存を排し、対象だけを純粋にテストできる
次回: リクエストと処理を疎結合につなぐMediatRです。
テンプレート構成(教材制作用メモ)
121-moq/
├── starter.zip # xUnit + Moq / IUserRepository・UserService / Tests(TODO入り)
└── solution/