简体   繁体   English

NHibernate在Nunit测试中出现奇怪的故障

[英]Strange failure in Nunit test with NHibernate

running a simple test with NUnit and FluentAssertion i have this messagge for failure: 使用NUnit和FluentAssertion运行一个简单的测试,我有这样的错误信息:

Expected object to be 

Gedi.Domain.Object.Entity.Persona
{
   Annullato = False
   Descrizione = "Persona1"
   Id = 1
}, but found 

Gedi.Domain.Object.Entity.Persona
{
   Annullato = False
   Descrizione = "Persona1"
   Id = 1
}.

but I do not see differences. 但我看不到差异。 which may be the cause of failure? 可能是失败的原因?

this is the test method 这是测试方法

public void CanSaveAndLoadDocumento()
    {
        //Arrange
        Documento documentoTarget = new Documento();
        Documento documentoActual;

        documentoTarget.Id = fixture.Create<int>();                 

        // Act
        using (IUnitOfWork uow = new UnitOfWork())
        {
            uow.Start();
            documentoTarget.Persona = uow.ServiceRepositoryFor<Persona>().GetById(1);
            uow.DocumentoRepository.Create(documentoTarget);
            uow.Commit();
            uow.CloseConnection();

            uow.Start();
            documentoActual = uow.DocumentoRepository.GetById(documentoTarget.Id);          
            uow.CloseConnection();
        }

        //Assert
        documentoActual.Persona.Should().Be(documentoTarget.Persona);

    }

Persona with ID = 1 is handwritten by me directly in database ID = 1的角色是我直接在数据库中手写的

this is the base repository i use with NHibernate 这是我与NHibernate一起使用的基本存储库

public abstract class RepositoryBase<TEntity, TKey> : IDisposable
    where TEntity : class, IKeyedEntity<TKey>
    where TKey : struct
{
    protected ISession _session;
    public RepositoryBase(ISession session)
    {
        _session = session;         
    }       
    public void Create(TEntity entity)
    {
        _session.SaveOrUpdate(entity);
    }       
    public TEntity GetById(TKey id)
    {
        return _session.Get<TEntity>(id);
    }
}

public class DocumentoRepository : RepositoryBase<Documento, int>
{
    public DocumentoRepository(ISession session)
        : base(session)
    {
    }
}

Reason is simple - DocumentoRepository.GetById(documentoTarget.Id) creates new instance of Persona entity instead of returning cached instance. 原因很简单DocumentoRepository.GetById(documentoTarget.Id)创建Persona实体的新实例,而不是返回缓存的实例。 Fluent assertions compares both entities by reference, and you have assertion failure. 流利的断言通过引用比较两个实体,并且断言失败。

You can implement Equals and GetHashCode for your Persona class. 您可以为Persona类实现EqualsGetHashCode Or use ShouldBeEquivlentTo for asserting object graph equivalence: 或使用ShouldBeEquivlentTo声明对象图等效性:

documentoActual.Persona.ShouldBeEquivlentTo(documentoTarget.Persona);

better version: in this way two object are equals if all properties are equals 更好的版本:这样,如果所有属性都相等,则两个对象相等

public abstract class EquatableObject<TObject>: IEquatable<TObject>
    where TObject : class   
{
    protected EquatableObject()
    {           
    }

    public override int GetHashCode()
    {
        IEnumerable<FieldInfo> fields = GetFields();
        int startValue = 17;
        int multiplier = 59;
        int hashCode = startValue;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(this);
            if (value != null)
                hashCode = hashCode * multiplier + value.GetHashCode();
        }
        return hashCode;
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        TObject other = obj as TObject;

        return Equals(other);

    }

    public virtual bool Equals(TObject other)
    {
        if (other == null)
            return false;

        Type t = GetType();
        Type otherType = other.GetType();

        if (t != otherType)
            return false;

        FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        foreach (FieldInfo field in fields)
        {
            object value1 = field.GetValue(other);
            object value2 = field.GetValue(this);

            if (value1 == null)
            {
                if (value2 != null)
                    return false;
            }
            else if (!value1.Equals(value2))
                return false;
        }
        return true;

    }

    private IEnumerable<FieldInfo> GetFields()
    {
        Type t = GetType();
        List<FieldInfo> fields = new List<FieldInfo>();
        while (t != typeof(object))
        {
            fields.AddRange(t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));

            t = t.BaseType;
        }
        return fields;
    }
}

OLD

Solved adding 解决了添加

public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        T other = obj as T;

        return Equals(other);

    }

to my class 到我班上

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

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