【C#】xUnit.netのAssertメソッドによる戻り値と状態の検証

目次

概要

xUnit.netにおいて、テスト対象メソッドの実行結果が期待通りであるかを判定するための基本的な検証(アサーション)実装です。 値の等価性(Equal)、真偽値(True/False)、nullチェック、およびオブジェクトの参照同一性(Same)を確認する手法を網羅します。

仕様(入出力)

  • 入力: テスト対象メソッドの戻り値、または評価したいオブジェクト
  • 出力: 検証結果(成功時は何も起きず、失敗時はXunit.Sdk.EqualException等の例外が発生しテスト失敗となる)
  • 前提: xunit パッケージがインストールされていること。

基本の使い方

[Fact]
public void BasicAssertion()
{
    // 期待値(10) と 実測値(result) を比較
    int result = 5 + 5;
    Assert.Equal(10, result);
}

コード全文

様々なパターン(等価、真偽、null、参照)の検証を行うテストクラスの例です。

using System;
using Xunit;

namespace UnitTestPatterns
{
    public class ResultVerificationTests
    {
        // テスト対象のロジック(本来は別クラスに定義されます)
        private static class Logic
        {
            public static string BuildId(string code) => $"ID-{code}";
            public static bool IsValidAge(int age) => age >= 18;
            public static object FindResource(int id) => id == 1 ? new object() : null;
        }

        [Fact]
        public void VerifyEquality()
        {
            // 値の等価性を検証
            string actual = Logic.BuildId("001");
            
            // Equal: 値が等しいか
            Assert.Equal("ID-001", actual);

            // NotEqual: 値が異なっているか
            Assert.NotEqual("ID-999", actual);
        }

        [Fact]
        public void VerifyBoolean()
        {
            // 真偽値の検証
            bool isAdult = Logic.IsValidAge(20);
            bool isChild = Logic.IsValidAge(10);

            // True: 条件が真であるか
            Assert.True(isAdult);

            // False: 条件が偽であるか
            Assert.False(isChild);
        }

        [Fact]
        public void VerifyNullability()
        {
            // nullかどうかの検証
            var found = Logic.FindResource(1);
            var missing = Logic.FindResource(99);

            // NotNull: インスタンスが存在するか
            Assert.NotNull(found);

            // Null: 結果がnullであるか
            Assert.Null(missing);
        }

        [Fact]
        public void VerifyReferences()
        {
            // オブジェクトの参照(メモリ上の同一性)を検証
            var obj1 = new object();
            var obj2 = obj1;            // 同じ参照
            var obj3 = new object();    // 別の参照

            // Same: 全く同じインスタンス(参照)か
            Assert.Same(obj1, obj2);

            // NotSame: 別のインスタンスか(値が同じでもインスタンスが別ならPass)
            Assert.NotSame(obj1, obj3);
        }
    }
}

カスタムポイント

  • 浮動小数点数の比較: doublefloatAssert.Equal で比較する場合、計算誤差を許容するために第3引数で精度(小数点以下の桁数)を指定することが推奨されます。 例: Assert.Equal(3.14159, value, 5);
  • コレクションの比較: 配列やリストの中身がすべて等しいかを確認する場合も Assert.Equal が使用できますが、順序を無視したい場合や要素ごとの検査が必要な場合は Assert.CollectionAssert.Contains を使用します。

注意点

  1. 引数の順序: Assert.Equal(expected, actual) の順序を守ってください。第1引数が「期待値」、第2引数が「実際の値」です。逆にしてしまうと、テスト失敗時のエラーメッセージ(ExpectedとActualの表示)が逆になり、原因調査が混乱します。
  2. 参照型とEqual: クラス(参照型)に対して Assert.Equal を使うと、デフォルトでは Assert.Same と同様に参照の比較になります。値としての等価性を比較したい場合は、そのクラスで Equals メソッドをオーバーライドするか、record 型を使用してください。
  3. True/Falseの乱用回避: Assert.True(a == b) と書くことは可能ですが、テストが失敗した際に「Falseでした」としか表示されません。Assert.Equal(a, b) を使えば「期待値はAですが実際はBでした」と詳細が表示されるため、可能な限り専用のAssertメソッドを使用してください。

応用

文字列の部分一致や正規表現による検証

完全一致ではなく、特定のフォーマットに従っているかを検証する例です。

[Fact]
public void VerifyStringPattern()
{
    string result = "Error: Connection timed out (Code: 504)";

    // 特定の文字列で始まっているか
    Assert.StartsWith("Error:", result);

    // 特定の文字列を含んでいるか
    Assert.Contains("timed out", result);

    // 正規表現にマッチするか
    Assert.Matches(@"Code: \d{3}", result);
}

まとめ

xUnit.netには目的に応じた豊富な検証メソッドが用意されています。基本的な値の比較には Equal を、状態の確認には True/FalseNull を、そしてオブジェクトそのものの同一性を確認する際には Same を使用します。適切なメソッドを選択することで、テスト失敗時に具体的で分かりやすいエラーメッセージが得られ、デバッグ効率が向上します。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次