[英]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
类实现Equals
和GetHashCode
。 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.