Testing if a Value is Within a Specific Range with xUnit.net in C#

目次

Overview

This implementation uses the Assert.InRange method in xUnit.net to verify if a test result is between a specific minimum and maximum value (inclusive). It works for integers, dates (DateTime), floating-point numbers, and any type that implements IComparable.

Specifications (Input/Output)

  • Input: The value to verify (Actual), the minimum value (Low), and the maximum value (High).
  • Output: Success if Low <= Actual <= High.
  • Failure: If the value is outside the range, Xunit.Sdk.InRangeException occurs and the test fails.
  • Prerequisite: The xunit package must be installed.

Basic Usage

[Fact]
public void CheckScoreRange()
{
    int score = 85;
    
    // Verify that the score is between 0 and 100
    Assert.InRange(score, 0, 100);
}

Full Code

This code tests whether the value returned by a random number generator falls within the expected range.

using System;
using Xunit;

namespace RangeTesting
{
    public class RangeTests
    {
        [Fact]
        public void GetInt_ReturnsValueBetween1And7()
        {
            var obj = new MySampleClass();

            // Since it is a random number, try multiple times to ensure no value is out of range
            for (int i = 0; i < 10; i++)
            {
                var value = obj.GetInt();

                // Verify that the value is between 1 and 7 (inclusive)
                // Random.Next(1, 8) returns 1 to 7, so this test should always pass
                Assert.InRange(value, 1, 7);
            }
        }

        [Fact]
        public void StaticValue_IsInRange()
        {
            // Example of verifying a fixed value
            // 1 is within the range of 1 to 17
            Assert.InRange(1, 1, 17);
        }

        [Fact]
        public void CheckNotInRange()
        {
            int value = 999;
            
            // Use NotInRange to verify that a value is "outside" the range
            Assert.NotInRange(value, 1, 10);
        }
    }

    /// <summary>
    /// Class to be tested
    /// </summary>
    public class MySampleClass
    {
        private readonly Random _rnd = new Random();

        /// <summary>
        /// Returns a random integer from 1 to 7
        /// </summary>
        public int GetInt()
        {
            // Next(minValue, maxValue) -> maxValue is exclusive
            return _rnd.Next(1, 8); 
        }
    }
}

Customization Points

  • Date Range Check: You can use this for DateTime as well as numbers.C#var dt = new DateTime(2025, 1, 1); Assert.InRange(dt, new DateTime(2024, 1, 1), new DateTime(2025, 12, 31));
  • Handling Boundary Values: Assert.InRange is “inclusive” (it includes the boundaries). For example, Assert.InRange(5, 5, 10) will succeed. If you want to exclude the boundaries, you must adjust the values in the test code or use Assert.True with < and > operators.

Points of Caution

  • Argument Order: The order is Assert.InRange(actual, low, high). The first argument is the value you want to verify. It is easy to confuse this order.
  • IComparable Implementation: If you want to check the range of a custom class instance, that class must implement the IComparable<T> interface.
  • Uncertainty in Random Testing: While the code example tests a Random class, real unit tests should ideally replace random elements with mocks (fake objects that return fixed values). Testing with actual randomness can cause “Flaky Tests” that fail only occasionally when an unexpected value appears.

Application

Range Check for double Type

You can use it similarly for floating-point numbers.

[Fact]
public void Temperature_IsSafe()
{
    double temperature = 36.5;
    
    // Check if it is within the range of 36.0 to 37.5 degrees
    Assert.InRange(temperature, 36.0, 37.5);
}

Summary

Assert.InRange is effective for any value that can be compared, such as numbers, dates, and times. It provides better readability than writing Assert.True(val >= min && val <= max) for validation logic or checking calculation results. It also makes debugging easier because it displays specific values when a test fails.

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

この記事を書いた人

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

目次