C # Сравнение нескольких объектов в модульном тестировании без переопределения - PullRequest
0 голосов
/ 18 октября 2018

Следующий тест создает ошибку при тестировании кортежей.

'Assert.AreEqual(test,productRepository.GetById(1))' threw an exception of type 'NUnit.Framework.AssertionException'

1) Как бы я решил эту проблему без переопределения?Многие решения, представленные ниже, требуют функции равных переопределений для каждой модели.Это не поддерживается в базе данных 500 модель +.Object.Equals также не работает.

2) Я читал об Autofixture, есть ли какой-нибудь особый метод в Nunit или недавние конкуренты Autofixture?(Похоже, Autofixture является наиболее популярным по сравнению с глубинными и ожидаемыми объектами).Существуют ли другие библиотеки Nuget?

Все они просят переопределить, только в одном ответе упоминается Autofixture

NUnit Test

[Test]
public void TestProducts()
{
    var options = new DbContextOptionsBuilder<ElectronicsContext>()
        .UseInMemoryDatabase(databaseName: "Products Test")
        .Options;

    using (var context = new ElectronicsContext(options))
    {
        //DbContextOptionsBuilder<ElectronicsContext> context = new DbContextOptionsBuilder<ElectronicsContext>()

        context.Product.Add(new Product { ProductId = 1, ProductName = "TV", ProductDescription = "TV testing", ImageLocation = "test" });
        context.SaveChanges();
        ProductRepository productRepository = new ProductRepository(context);
        var test = new Product
            {ProductId = 1, ProductName = "TV", ProductDescription = "TV testing", ImageLocation = "test"};

       **//This works**
        Assert.AreEqual("TV", productRepository.GetById(1).ProductName);

       **//This Fails**
        Assert.AreEqual(test,productRepository.GetById(1));

       **//This Fails**
        Assert.AreEqual(Object.Equals(test, productRepository.GetById(1)), 1);
    }

Репозиторий

public class ProductRepository : IProductRepository<Product>
{
    private readonly ElectronicsContext _context;
    public ProductRepository(ElectronicsContext context)
    {
        _context = context;
    }

    public IEnumerable<Product> GetAllProduct()
    {
        return _context.Product.ToList();
    }

    public IQueryable<Product> Products => _context.Product;

    public Product GetById(int productid)
    {
        return _context.Product.Find(productid);

    }
}

Модель

public partial class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public string ProductDescription { get; set; }
    public string ImageLocation { get; set; }

    public int? ProductCategoryId { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
}

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Вы боретесь против определения C # равенства объектов, так что это проигрышная битва.Вам неизбежно нужно определить равенство объектов для каждого из ваших классов.Но это можно сделать с небольшим трудом - вы определяете его в базовом классе и наследуете.

Давайте определим 2 класса:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Product2 : DomainEntityIntPK
{
    public string Name { get; set; }
}

В этом случае я бы вывел все свои "бизнес-сущность "классы от DomainEntityIntPK.Это класс, который занимается концепцией равенства бизнеса.

Вот модульные тесты и результаты:

[TestFixture]
public class UnitTest1
{
    [Test]
    public void TestMethodProduct()
    {
        Product p1 = new Product{ Id=1, Name="Foo" };
        Product p2 = new Product{ Id=1, Name="Foo" };
        Assert.AreEqual( p1, p2 );
    }

    [Test]
    public void TestMethodProduct2()
    {
        Product2 p1 = new Product2{ Id=1, Name="Foo" };
        Product2 p2 = new Product2{ Id=1, Name="Foo" };
        Assert.AreEqual( p1, p2 );
    }
}

enter image description here

А отсутствующим элементом, конечно же, является базовый класс:

public abstract class DomainEntityIntPK
{
    public int Id { get; set; }

    public static bool operator ==( DomainEntityIntPK lhs, DomainEntityIntPK rhs )
    {
        return Equals( lhs, rhs );
    }

    public static bool operator !=( DomainEntityIntPK lhs, DomainEntityIntPK rhs )
    {
        return !Equals( lhs, rhs );
    }

    public override Boolean Equals( object obj )
    {
        DomainEntityIntPK other = obj as DomainEntityIntPK;
        if( other == null ) return false;

        Boolean thisIsNew = Id == 0;
        Boolean otherIsNew = other.Id == 0;
        if( thisIsNew && otherIsNew )
        {
            Boolean referenceEquals =  ReferenceEquals( this, other );
            return referenceEquals;
        }

        Boolean idEquals = Id.Equals( other.Id );
        return idEquals;
    }
}
0 голосов
/ 18 октября 2018

Чтобы не переопределять метод Equals, вы обычно создаете реализацию IEqualityComparer<T>, где T - это тип, который вы хотите сравнить, в вашем случае Product.

Inв компараторе вы должны реализовать методы bool Equals(T x, T y) и int GetHashCode(T obj).

Ваш может выглядеть примерно так:

public class ProductComparer : IEqualityComparer<Product>
{
    // Implement Equals and GetHashCode
}

Тогда вы можете использовать его так:

var actual = new List<int>();
var expected = new List<int>();
var comparer = new ProductComparer();

Assert.That(actual, Is.EqualTo(expected).Using(comparer));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...