[C#] Verifying Return Values and State with xUnit.net Assert Methods

目次

Overview

This implementation covers basic assertions in xUnit.net to determine if the execution result of a target method matches expectations. It encompasses techniques for verifying value equality (Equal), boolean values (True/False), null checks, and object reference identity (Same).

Specifications (Input/Output)

  • Input: The return value of the method under test or the object to be evaluated.
  • Output: Verification result (if successful, nothing happens; if it fails, an exception such as Xunit.Sdk.EqualException is thrown, and the test fails).
  • Prerequisite: The xunit package must be installed.

Basic Usage

[Fact]
public void BasicAssertion()
{
    // Compare Expected (10) and Actual (result)
    int result = 5 + 5;
    Assert.Equal(10, result);
}

Full Code Example

The following is an example of a test class that verifies various patterns: equality, boolean, nullability, and references.

using System;
using Xunit;

namespace UnitTestPatterns
{
    public class ResultVerificationTests
    {
        // Target logic (typically defined in a separate class)
        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()
        {
            // Verify value equality
            string actual = Logic.BuildId("001");
            
            // Equal: Are the values equal?
            Assert.Equal("ID-001", actual);

            // NotEqual: Are the values different?
            Assert.NotEqual("ID-999", actual);
        }

        [Fact]
        public void VerifyBoolean()
        {
            // Verify boolean values
            bool isAdult = Logic.IsValidAge(20);
            bool isChild = Logic.IsValidAge(10);

            // True: Is the condition true?
            Assert.True(isAdult);

            // False: Is the condition false?
            Assert.False(isChild);
        }

        [Fact]
        public void VerifyNullability()
        {
            // Verify if null
            var found = Logic.FindResource(1);
            var missing = Logic.FindResource(99);

            // NotNull: Does the instance exist?
            Assert.NotNull(found);

            // Null: Is the result null?
            Assert.Null(missing);
        }

        [Fact]
        public void VerifyReferences()
        {
            // Verify object references (identity in memory)
            var obj1 = new object();
            var obj2 = obj1;            // Same reference
            var obj3 = new object();    // Different reference

            // Same: Are they the exact same instance (reference)?
            Assert.Same(obj1, obj2);

            // NotSame: Are they different instances? 
            // (Passes even if values are identical but instances are separate)
            Assert.NotSame(obj1, obj3);
        }
    }
}

Customization Points

  • Comparing Floating-Point Numbers: When comparing double or float with Assert.Equal, it is recommended to specify precision (number of decimal places) as the third argument to allow for calculation errors.
    • Example: Assert.Equal(3.14159, value, 5);
  • Comparing Collections: Assert.Equal can also be used to check if all contents of arrays or lists are equal. If you want to ignore order or inspect individual elements, use Assert.Collection or Assert.Contains.

Important Notes

  • Argument Order: Strictly follow the order of Assert.Equal(expected, actual). The first argument is the “expected value” and the second is the “actual value.” Reversing them leads to confusing error messages (Expected vs. Actual) during failure analysis.
  • Reference Types and Equal: By default, using Assert.Equal on a class (reference type) results in a reference comparison, similar to Assert.Same. To compare them based on value equality, override the Equals method in that class or use record types.
  • Avoid Overusing True/False: While Assert.True(a == b) is possible, it only displays “False” upon failure. Using Assert.Equal(a, b) provides details like “Expected A but was B,” significantly aiding debugging.

Advanced Usage

Verification using Partial Matches or Regular Expressions

This example demonstrates verifying if a string follows a specific format rather than an exact match.

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

    // Does it start with a specific string?
    Assert.StartsWith("Error:", result);

    // Does it contain a specific string?
    Assert.Contains("timed out", result);

    // Does it match a regular expression?
    Assert.Matches(@"Code: \d{3}", result);
}

Summary

xUnit.net provides a rich set of verification methods tailored to different purposes. Use Equal for basic value comparisons, True/False or Null for state checks, and Same to confirm the identity of objects. Selecting the appropriate method ensures specific and easy-to-understand error messages when a test fails, improving debugging efficiency.

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

この記事を書いた人

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

目次