Object-Oriented Programming/Unit Testing/C Sharp

test.cs edit

using Xunit;

namespace Temperature.Tests
{
    public class UnitTests
    {
        [Fact]
        public void Constructor_CelsiusIsNull_Test()
        {
            var temperature = new Temperature();
            Assert.Equal(0, temperature.Celsius);
        }

        [Fact]
        public void Constructor_FahrenheitIsNull_Test()
        {
            var temperature = new Temperature();
            Assert.Equal(0, temperature.Fahrenheit);
        }

        [Fact]
        public void Constructor_CelsiusIsNotNull_Test()
        {
            var random = new System.Random();
            var value = random.Next(1, 100);

            var temperature = new Temperature(celsius: value);
            Assert.Equal(value, temperature.Celsius);
        }

        [Fact]
        public void Constructor_FahrenheitIsNotNull_Test()
        {
            var random = new System.Random();
            var value = random.Next(1, 100);

            var temperature = new Temperature(fahrenheit: value);
            Assert.Equal(value, temperature.Fahrenheit);
        }

        [Fact]
        public void Celsius_Value_Test()
        {
            var random = new System.Random();
            var value = random.Next(1, 100);

            var temperature = new Temperature();
            temperature.Celsius = value;
            Assert.Equal(value, temperature.Celsius);
        }

        [Fact]
        public void Fahrenheit_Value_Test()
        {
            var random = new System.Random();
            var value = random.Next(1, 100);

            var temperature = new Temperature();
            temperature.Fahrenheit = value;
            Assert.Equal(value, temperature.Fahrenheit);
        }

        [Fact]
        public void Constructor_CelsiusSetsFahrenheit_Test()
        {
            var temperature = new Temperature(celsius: 37);
            Assert.Equal(98.6, temperature.Fahrenheit);
        }

        [Fact]
        public void Constructor_FahrenheitSetsCelsius_Test()
        {
            var temperature = new Temperature(fahrenheit: 98.6);
            Assert.Equal(37, temperature.Celsius);
        }

        [Fact]
        public void AbsoluteZero_Celsius_Test()
        {
            var temperature = new Temperature();
            Assert.Equal(-273.15, temperature.AbsoluteZeroCelsius);
        }

       [Fact]
        public void AbsoluteZero_Fahrenheit_Test()
        {
            var temperature = new Temperature();
            Assert.Equal(-459.67, temperature.AbsoluteZeroFahrenheit);
        }

       [Fact]
        public void Celsius_ToFahrenheit_Test()
        {
            var temperature = new Temperature();
            Assert.Equal(98.6, temperature.ToFahrenheit(37));
        }

       [Fact]
        public void Fahrenheit_ToCelsius_Test()
        {
            var temperature = new Temperature();
            Assert.Equal(37, temperature.ToCelsius(98.6));
        }

       [Fact]
        public void ValidateCelsius_BelowAbsoluteZero_Test()
        {
            var random = new System.Random();
            var value = random.Next(-1000, -500);

            var temperature = new Temperature();
            Assert.Throws<System.ArgumentException>(() =>
                temperature.Celsius = value
            );
        }

       [Fact]
        public void ValidateFahrenheit_BelowAbsoluteZero_Test()
        {
            var random = new System.Random();
            var value = random.Next(-1000, -500);

            var temperature = new Temperature();
            Assert.Throws<System.ArgumentException>(() =>
                temperature.Fahrenheit = value
            );
        }
    }
}

temperature.cs edit

/// <summary>
/// Temperature converter. Provides temperature conversion functions. Supports Fahrenheit and Celsius temperatures.
/// </summary>
/// <remarks>
/// Examples:
///    var temperature = new Temperature(celsius: 37);
///    Console.WriteLine(temperature.Fahrenheit);
///    
///    temperature = new Temperature(fahrenheit: 98.6);
///    Console.WriteLine(temperature.Celsius);
///    
///    temperature = new Temperature();
///    temperature.Celsius = 37;
///    Console.WriteLine(temperature.Fahrenheit);
///    
///    temperature = new Temperature();
///    temperature.Fahrenheit = 98.6;
///    Console.WriteLine(temperature.Celsius);
///    
///    temperature = new Temperature();
///    Console.WriteLine(temperature.ToCelsius(98.6));
///    Console.WriteLine(temperature.ToFahrenheit(37)); 
///
/// References:
///   https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments
///   https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/nullable-value-types
///   https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
/// </remarks>

public class Temperature
{
    private double _celsius;
    private double _fahrenheit;

    /// <summary>
    /// Creates a Temperature object.
    /// Throws ArgumentException if both celsius and fahrenheit are initialized.
    /// </summary>
    public Temperature(double? celsius=null, double? fahrenheit=null)
    {
        if (celsius != null && fahrenheit != null)
        {
            throw new System.ArgumentException("Only initialize celsius or fahrenheit, not both.");
        }

        if (celsius != null)
        {
            Celsius = (double)celsius;
        }

        if (fahrenheit != null)
        {
            Fahrenheit = (double)fahrenheit;
        }
    }

    /// <summary>
    /// Returns absolute zero Celsius.
    /// </summary>
    public double AbsoluteZeroCelsius
    {
        get
        {
            return -273.15;
        }
    }
    
    /// <summary>
    /// Returns absolute zero Fahrenheit.
    /// </summary>
    public double AbsoluteZeroFahrenheit
    {
        get
        {
            return -459.67;
        }
    }

    /// <summary>
    /// Gets and sets Celsius temperature.
    /// </summary>
    public double Celsius
    {
        get
        {
            return _celsius;
        }

        set
        {
            _celsius = ValidateCelsius(value);
            _fahrenheit = ToFahrenheit(value);
        }
    }

    /// <summary>
    /// Gets and sets Fahrenheit temperature.
    /// </summary>
    public double Fahrenheit
    {
        get
        {
            return _fahrenheit;
        }

        set
        {
            _fahrenheit = ValidateFahrenheit(value);
            _celsius = ToCelsius(value);
        }
    }

    /// <summary>
    /// Converts Fahrenheit temperature to Celsius.
    /// </summary>
    public double ToCelsius(double fahrenheit)
    {
        fahrenheit = ValidateFahrenheit(fahrenheit);
        return (fahrenheit - 32) * 5 / 9;
    }

    /// <summary>
    /// Converts Celsius temperature to Fahrenheit.
    /// </summary>
    public double ToFahrenheit(double celsius)
    {
        celsius = ValidateCelsius(celsius);
        return celsius * 9 / 5 + 32;
    }

    /// <summary>
    /// Validates Celsius temperature.
    /// Throws error if Celsius temperature is below absolute zero.
    /// </summary>
    private double ValidateCelsius(double celsius)
    {
        if (celsius < AbsoluteZeroCelsius) {
            throw new System.ArgumentException("celsius must not be below absolute zero (" +
                AbsoluteZeroCelsius + "). Received " + celsius);
        }

        return celsius;
    }

    /// <summary>
    /// Validates Fahrenheit temperature.
    /// Throws error if Fahrenheit temperature is below absolute zero.
    /// </summary>
    private double ValidateFahrenheit(double fahrenheit)
    {
        if (fahrenheit < AbsoluteZeroFahrenheit) {
            throw new System.ArgumentException("fahrenheit must not be below absolute zero (" +
                AbsoluteZeroFahrenheit + "). Received " + fahrenheit);
        }

        return fahrenheit;
    }
}

Try It edit

Copy and paste the code above into one of the following free online development environments or use your own C Sharp compiler / interpreter / IDE.

See Also edit