使用NHibernate进行Nunit测试时出现奇怪的故障

时间:2014-08-08 10:06:58

标签: c# testing nhibernate nunit fluent-assertions

使用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
}.

但我没有看到差异。这可能是失败的原因?

这是测试方法

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

    }

ID = 1的角色由我直接在数据库中手写

这是我与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)
    {
    }
}

2 个答案:

答案 0 :(得分:4)

原因很简单 - DocumentoRepository.GetById(documentoTarget.Id)创建Persona实体的新实例,而不是返回缓存实例。 Fluent断言通过引用比较两个实体,并且您有断言失败。

您可以为Equals课程实施GetHashCodePersona。或者使用ShouldBeEquivlentTo来断言对象图等价:

documentoActual.Persona.ShouldBeEquivlentTo(documentoTarget.Persona);

答案 1 :(得分:-1)

更好的版本: 这样,如果所有属性都等于

,则两个对象相等
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

解决了添加

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

        T other = obj as T;

        return Equals(other);

    }

到我的班级