Как сравнить 2 экземляра класса внутри юнит теста?

У меня есть библиотека, которая работает с комплексными числами. Но одним из критериев оценивания работа (это вузовская домашка) является наличие и корректность UNIT-тестов. Но при попытке сравнить 2 экземпляра класса, тест валится. Ниже сам тест:

public void TestMethod1()
{
    Complex first = new Complex(2, 4);
    Complex second = new Complex(0, 0);
    Complex expected = new Complex(2, 4);
    CollectionAssert.AreEqual(expected, first + second);
}

Сама работа (включает класс для работы с полярными координатами):

{


 public class Complex
    {
        private double real;
        private double img;

        public Complex(double real, double img)
        {
            real = real;
            img = img;
        }
        public static Complex operator +(Complex first, Complex second)
        {
            return new Complex(first.real + second.real, first.img + second.img);
        }
        public static Complex operator -(Complex first, Complex second)
        {
            return new Complex(first.real - second.real, first.img - second.img);
        }
        public static Complex operator *(Complex first, Complex second)
        {
            double real = first.real * second.real - first.img * second.img;
            double img = first.real * second.img + first.img * second.real;
            return new Complex(real, img);
        }
        public static Complex operator /(Complex first, Complex second)
        {
            double real = (first.real * second.real + first.img * second.img) / (second.real * second.real + second.img * second.img);
            double img = (second.real * first.img - first.real * second.img) / (second.real * second.real + second.img * second.img);
            return new Complex(real, img);
        }
        public string ToComplexString()
        {
            return this.real > 0 ? $"{this.real}+{this.img}i" : $"{this.real}{this.img}i";
        }
        public Complex ComplexPow(double n)
        {
           double module = Math.Sqrt(this.real * this.real + this.img * this.img);
           module = Math.Round(module, 2);
           double argue = Math.Atan(this.img / this.real);
           argue = Math.Round(argue, 2);
           Complex z = new Complex(module * Math.Cos(argue), module * Math.Sin(argue));
           return new Complex(z.real * n, z.img * n);
        }

        public Polar ToPolar()
        {
            double value = Math.Sqrt(this.img * this.img + this.real * this.real);
            double angle = 0;
            if (this.real > 0 && this.img >= 0) angle = Math.Atan(this.img / this.real);
            if (this.real > 0 && this.img < 0) angle = Math.Atan(this.img / this.real) + 2 * Math.PI;
            if (this.real < 0) angle = Math.Atan(this.img / this.real) + Math.PI;
            if (this.real == 0 && this.img > 0) angle = Math.PI / 2;
            if (this.real == 0 && this.img < 0) angle = 3 *Math.PI / 2;
            if (this.real == 0 && this.img == 0) angle = 0;
            value = Math.Round(value, 2);
            angle = Math.Round(angle, 2);
            return new Polar(value, angle);
        }
    }
}

public class Polar
{
    private double value;
    private double angle;

    public Polar(double _value, double _angle)
    {
        value = _value;
        angle = _angle;
    }

    public Complex ToComplex()
    {
        return new Complex(this.value * Math.Cos(angle), this.value * Math.Sin(angle));
    }
    public static Polar operator +(Polar first, Polar second)
    {
        
        Complex a = first.ToComplex();
        Complex b = second.ToComplex();
        return ((a + b).ToPolar());
    }
    public static Polar operator -(Polar first, Polar second)
    {
        Complex a = first.ToComplex();
        Complex b = second.ToComplex();
        return ((a - b).ToPolar());
    }
    public static Polar operator *(Polar first, Polar second)
    {
        Complex a = first.ToComplex();
        Complex b = second.ToComplex();
        return ((a * b).ToPolar());
    }
    public static Polar operator /(Polar first, Polar second)
    {
        Complex a = first.ToComplex();
        Complex b = second.ToComplex();
        return ((a / b).ToPolar());
    }

    public string PolarToString()
    {
        return $"{this.value} ∠{this.angle}";
    }
}

Ответы (1 шт):

Автор решения: Andrei Khotko

Тест должен сравнивать не сами объекты Complex, а значения, которые определяют равенство этих объектов. В вашем случае, это img и real. Но они приватные. Чтобы сравнить два объекта класса Complex, есть несколько вариантов:

  1. Сделать img и real публичными и вызывать Assert.AreEqual() 2 раза - для img и real;
  2. Использовать строковое представление числа (вызывая метод ToComplexString()), которое определяется как раз нужными значениями;
  3. Реализовать интерфейс IEquatable на вашем классе.

Пока покажу вариант #2, он требует меньше всего времени, но качество тестов зависит от правильной реализации метода ToComplexString():

public void TestMethod1()
{
    Complex first = new Complex(2, 4);
    Complex second = new Complex(0, 0);
    Complex expected = new Complex(2, 4);
    Complex actual = first + second;
    
    Assert.AreEqual(expected.ToComplexString(), actual.ToComlexString());
}

P.S. Assert.AreEqual() для чисел с плавающей точкой имеет третий аргумент - точность сравнения. Используйте его в ваших тестах, т.к. числа с плавающей точкой при сравнении на равенство могут выдавать неожиданные результаты.

→ Ссылка