web-dev-qa-db-ja.com

XUnitの記述的なアサートメッセージの実装方法

コンテキスト

xUnit githubで私はこれを見つけました: Add Assert.Equal(expected、actual、message)overload#35(だから開発者は以下の非既存のオーバーロードを求めます)

答えから引用:

私たちは自己文書化コードを信じています。それにはあなたの主張が含まれます。

(XUnitチームはそれを拒否します)

はい、分かりました。自己文書化コードも信じています。それでも私はこのユースケースを見つけることができません:

サンプル

// Arrange
// Create some external soap service client and its wrapper classes

// Act
// client.SomeMethod();

// Assert
// Sorry, soap service's interface, behaviour and design is *given*
// So I have to check if there is no Error, and 
// conveniently if there is, then I would like to see it in the assertion message

Assert.Equal(0, client.ErrorMessage.Length); // Means no error

// I would like to have the same result what would be the following *N*U*n*i*t* assert:
// Assert.AreEqual(0, client.ErrorMessage.Length, client.ErrorMessage); // Means no error

質問

この場合、このようなオーバーロードがまだないXUnitで説明的なアサートメッセージを実装するにはどうすればよいですか?

24
g.pickardou

リンクで提供される提案を使用してください。 fluent assertions のように、またはメッセージのオーバーロードで残されたAssert.True or Assert.Falseをラップする独自のアサーションを作成します。さらに下に言及されました

引用

Assert.Trueおよび.Falseにメッセージを提供できます。メッセージなしでは生きていけない(そして別のアサーションの使用を拒否する)場合は、常に以下にフォールバックできます。

Assert.True(number == 2, "This is my message");

引用:

メッセージが本当に必要な場合は、テストプロジェクトに Fluent Assertions または多分 xbehave を追加して、その構文を使用できます。 Fluent Assertionsは、存在する場合、xunit.net例外をスローします。

16
Nkosi

私は同じ問題を抱えていました。 2つのWeb APIからデータを取得し、コンテンツに関するさまざまなことを比較してアサートするテストを行いました。私は次のような標準のXUnitアサーションを使い始めました。

Assert.Equal(HttpStatusCode.OK, response1.StatusCode);
Assert.Equal(HttpStatusCode.OK, response2.StatusCode);

ただし、これにより404が返されたという有用なメッセージが表示されますが、ビルド/ CIサーバーのログからは、どのサービスがエラーメッセージの原因であるかがわかりません。

コンテキストを与えるために、私は自分のアサーションを追加することになりました:

public class MyEqualException : Xunit.Sdk.EqualException
{
    public MyEqualException(object expected, object actual, string userMessage)
        : base(expected, actual)
    {
        UserMessage = userMessage;
    }

    public override string Message => UserMessage + "\n" + base.Message;
}

public static class AssertX
{
    /// <summary>
    /// Verifies that two objects are equal, using a default comparer.
    /// </summary>
    /// <typeparam name="T">The type of the objects to be compared</typeparam>
    /// <param name="expected">The expected value</param>
    /// <param name="actual">The value to be compared against</param>
    /// <param name="userMessage">Message to show in the error</param>
    /// <exception cref="MyEqualException">Thrown when the objects are not equal</exception>
    public static void Equal<T>(T expected, T actual, string userMessage)
    {
        bool areEqual;

        if (expected == null || actual == null)
        {
            // If either null, equal only if both null
            areEqual = (expected == null && actual == null);
        }
        else
        {
            // expected is not null - so safe to call .Equals()
            areEqual = expected.Equals(actual);
        }

        if (!areEqual)
        {
            throw new MyEqualException(expected, actual, userMessage);
        }
    }
}

その後、次と同じアサーションを実行できます。

AssertX.Equal(HttpStatusCode.OK, response1.StatusCode, $"Fetching {Uri1}");
AssertX.Equal(HttpStatusCode.OK, response2.StatusCode, $"Fetching {Uri2}");

エラーログは、実際の、予想されるものを提供し、どのwebapiが原因であるかについての私のメッセージを追加します。

私は答えるのが遅いことに気付きますが、これは、テストの失敗から有用な情報を取得するためだけに別のテストフレームワークをインストール/学習する時間がない実用的なソリューションを探している人に役立つかもしれないと考えました。

5
Grhm