繁体   English   中英

C#比较单元测试中的多个对象而无需覆盖

[英]C# Comparing Multiple Objects in Unit Testing without Overriding

当测试元组时,以下测试会产生错误。

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

1)我将如何解决这个问题而不至于压倒一切? 下面介绍的许多解决方案都要求每个模型都具有覆盖等于功能。 这在500型以上的数据库中无法维护。 Object.Equals也不起作用。

2)我读过有关Autofixture的文章,在Nunit或最近的竞争对手中有没有什么特别的方法可以使用Autofixture? (相比于Deepequals和预期对象,似乎Autofixture最流行)。 还有其他Nuget库吗?

这些都要求覆盖,只有一个答案提到自动修复

NUnit测试

[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; }
}

为了避免覆盖Equals方法,通常应创建IEqualityComparer<T>的实现,其中T是要比较的类型(在本例中为Product

在比较器中,必须实现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));

您正在与对象平等的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 );
    }
}

在此处输入图片说明

当然,缺少的元素是基类:

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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM