本文へスキップ
BecomeCoder

C#デザインパターンコース · 第2章 TDD ― テスト駆動開発 · レッスン18

FluentAssertions ― 読みやすい検証

ブラウザで完結

導入

Assert.Equal(expected, actual)より、文章のように読める検証を書けるNuGetライブラリがFluentAssertionsです。actual.Should().Be(expected)という語順で、失敗メッセージも分かりやすくなります。

図解

flowchart LR
    A["Assert.Equal(5, x)"] -->|書き換え| B["x.Should().Be(5)"]
    B --> R["主語→検証と読める<br/>失敗メッセージも文章的"]
    style B fill:#e8f5e9

サンプル

FluentAssertionsの記法はこうです(ローカルでNuGetを入れて使います)。

// --- FluentAssertions の記法(読み物) ---
// order.Total.Should().Be(3200);
// order.Total.Should().BeGreaterThan(0);
// order.Items.Should().HaveCount(2);
// order.Items.Should().Contain("本");

// 対応表: Assert.Equal(3200, x)      → x.Should().Be(3200)
//         Assert.True(x > 0)         → x.Should().BeGreaterThan(0)
//         Assert.Contains("本", list) → list.Should().Contain("本")

ブラウザでは「文章的な検証ヘルパー」を自作して考え方を体感します。検証の道具(Checker.cs)と、それを使うテスト(Program.cs)は別ファイルです。

1. 検証の道具(Checker.cs)。各メソッドがthisを返すのでチェーンできます(Builderと同じ手口)。

public class Checker
{
    private readonly int _value;
    public Checker(int value) => _value = value;

    public Checker Be(int expected)
    {
        if (_value != expected) throw new Exception($"期待 {expected} だが {_value}");
        return this;   // メソッドチェーンで続けて検証できる
    }

    public Checker BeGreaterThan(int min)
    {
        if (_value <= min) throw new Exception($"{_value} は {min} より大きくない");
        return this;
    }
}

2. テスト(Program.cs)。主語→検証の語順で読めることを確かめてください。

int total = 3200;
Check(total).Be(3200).BeGreaterThan(0);
Console.WriteLine("検証成功");

Checker Check(int value) => new Checker(value);
  • actual.Should().Be(expected)のように、主語→検証の語順で読める
  • BeGreaterThan / HaveCount / Containなど豊富な検証メソッドがある
  • 失敗メッセージが文章的で、CIが赤くなったとき原因が掴みやすい
  • 検証ヘルパーを別ファイルに切り出せば、どのテストからも使い回せる

演習

Check("hello").HaveLength(5).StartWith("he");
Console.WriteLine("検証成功");

// TODO: 文字列用の検証ヘルパー StringChecker を完成させてください。
//       HaveLength(int)(長さ一致)と StartWith(string)(先頭一致)を実装し、
//       いずれも this を返してチェーンできるようにします
//       (int用の Checker.cs はそのまま残し、文字列用は別のクラスとして足します)
StringChecker Check(string value) => new StringChecker(value);
___
  • 期待される出力: 検証成功
ヒント1を見る

class StringChecker { private readonly string _v; public StringChecker(string v) => _v = v; public StringChecker HaveLength(int n) { if (_v.Length != n) throw new Exception(); return this; } public StringChecker StartWith(string p) { if (!_v.StartsWith(p)) throw new Exception(); return this; } }

ヒント2を見る

各メソッドの最後でreturn this;するとチェーンできます

まとめ

  • FluentAssertionsはx.Should().Be(y)で読みやすい検証を書く
  • 豊富な検証メソッドと分かりやすい失敗メッセージが利点
  • Moqと合わせて実務テストの二大NuGetライブラリ

次章: 待ち時間を有効に使う「非同期プログラミング」へ進みます。

実際に動かしてみよう

このレッスンのサンプルは、実務と同じように役割ごとの .cs ファイルへ分けてあります。下のエディタは最初からその複数ファイルが入った状態で、上のタブでファイルを切り替えられます。そのまま「▶ 実行」を押せば全ファイルをまとめてコンパイルして動かせるので、クラスを足したりファイルをまたいで書き換えたりしながら進めましょう(演習は本文のコードをコピーして Program.cs のタブに貼り付ければ試せます)。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。

次のレッスンへ →