xUnit сравнивает равенство объектов

У меня есть этот класс с его конструктором

 public class BankAccount
    {
    public int Id { get; private set; }
    public int BankAccountNo { get; private set; }
    public decimal Balance { get; private set; }

    public BankAccount(int BankAccountNo, decimal Balance)
    {
        this.BankAccountNo = BankAccountNo;

        if(Balance <= 0)
        {
            throw new ArgumentException("Create bank account failed. Balance should be more than zero.");
        }

        this.Balance = Balance;
    }
}

Я создал модульный тест xunit для проверки равенства объектов

открытый класс BankAccountTest { частный BankAccount _bankAccount;

    public BankAccountTest()
    {
        _bankAccount = new BankAccount();
    }

    [Theory, MemberData(nameof(BankAccountConstructorShouldPass_Data))]
    public void BankAccountConstructorShouldPass(BankAccount account, BankAccount accountExpected)
    {
        // Act
        _bankAccount = new BankAccount(account.BankAccountNo, account.Balance);

        // Assert
        Assert.Equal<BankAccount>(accountExpected,_bankAccount);
    }

    public static TheoryData<BankAccount, BankAccount> BankAccountConstructorShouldPass_Data()
    {
        return new TheoryData<BankAccount, BankAccount>
        {
            {
                new BankAccount(123, 250.00M),        
                new BankAccount(123, 250.00M)
            },
            {
                new BankAccount(321, 150.50M),       
                new BankAccount(321, 150.50M)
            }
        };
    }
}

Когда я запускаю тест, он не работает с ошибкой

Assert.Equal() Failure
Expected: BankAccount { Balance = 250.00, BankAccountNo = 123, Id = 0 }
Actual:   BankAccount { Balance = 250.00, BankAccountNo = 123, Id = 0 }

Я пробовал с Assert.True(accountExpected.Equals(_bankAccount));, но безуспешно.


person Steve    schedule 16.06.2020    source источник
comment
Отвечает ли это на ваш вопрос? Лучший способ сравнить два сложных объекта. Вы всегда можете сериализовать их обоих и проверить полученные строки.   -  person Jawad    schedule 16.06.2020
comment
Google для xunit compare two objects. buildplease.com/pages/testing-deep-equalilty   -  person mjwills    schedule 16.06.2020
comment
Спасибо. Удалось решить это с помощью FluentAssertions. accountExpected.Should().BeEquivalentTo(_bankAccount);. Но я пока не могу понять, как это решить без FluentAssertions.   -  person Steve    schedule 16.06.2020


Ответы (2)


Вы пытаетесь сравнить два объекта, которые не являются Equatable! В C#, чтобы иметь возможность сравнивать два объекта, они должны быть Equatable, другими словами, базовый класс должен реализовать IEquatable, если вы не реализуете IEquatable<T> для ссылочного типа, проверка на равенство просто проверит ссылки на объекты! (обратите внимание, что это поведение отличается для типов значений!)

Итак, что вам нужно сделать, это одно из следующих действий:

  1. Реализуйте IEquatable для своего класса BackAccount, следуя инструкциям Как определить равенство значений для типа
  2. В качестве альтернативы вы можете сравнить отдельные поля по одному:
Assert.Equal(bankAccount1.Balance, bankAccount2.Balance)

Также вот хороший пост в блоге об утверждении равенства:

person Arin Ghazarian    schedule 16.06.2020

Утверждение не выполняется, потому что вы сравниваете местоположение ссылки на объект в памяти. Вместо этого вы должны утверждать свойства внутри объекта.

https://medium.com/@pjbgf/asserting-equality-in-your-c-unit-tests-837b423024bf#:~:text=Equal(expected.Name%2C%20actual,object%20within%20the%20memory%20heap.

person Jeff    schedule 16.06.2020