本文へスキップ
BecomeCoder

C#実践コース · 第6章 代表的なNuGetパッケージとその使い方 · レッスン37

Moq ― 単体テストで依存を差し替える(ローカル実施)

ローカル実施

導入

テスト駆動開発(TDD)はすでに学びました。実務では「DBや外部API(=遅い・不安定)」に依存するクラステストしたい場面が多くあります。Moqは、インターフェースの**偽物(モック)**をその場で作り、「このメソッドが呼ばれたらこの値を返す」と振る舞いを指定して、対象クラスだけを純粋にテストできるようにします。

図解

flowchart LR
    TEST["テスト"] -->|本物の代わりに注入| MOCK["Mock&lt;IUserRepository&gt;<br/>Setup で戻り値を固定"]
    MOCK --> SUT["UserService(テスト対象)"]
    SUT --> TEST
    TEST -->|Verify| MOCK

進め方

  1. スターター121-moq/starter.zipを展開し、MoqLesson.slnを開く(xUnit + Moq導入済み)
  2. テストのTODO(Setup / Verify)を埋める
  3. テストエクスプローラーで緑になることを確認する
Visual Studioのテストエクスプローラーで、Moqを使った単体テストがすべて成功(緑)になった様子
本物のリポジトリなしで、サービスの振る舞いだけを検証できる

学ぶこと

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/