I was asked to show how you can easily do CRUD tests, so here’s a base class that makes it very easy
public abstract class CrudTest<TEntity, TId> : NHibernateTest
where TEntity : IHaveAnId<TId>
{
[Test]
public virtual void SelectQueryWorks()
{
session.CreateCriteria(typeof(TEntity)).SetMaxResults(5).List();
}
[Test]
public virtual void AddEntity_EntityWasAdded()
{
var entity = BuildEntity();
InsertEntity(entity);
session.Evict(entity);
var reloadedEntity = session.Get<TEntity>(entity.Id);
Assert.IsNotNull(reloadedEntity);
AssertAreEqual(entity, reloadedEntity);
AssertValidId(reloadedEntity);
}
[Test]
public virtual void UpdateEntity_EntityWasUpdated()
{
var entity = BuildEntity();
InsertEntity(entity);
ModifyEntity(entity);
UpdateEntity(entity);
session.Evict(entity);
var reloadedEntity = session.Get<TEntity>(entity.Id);
Assert.IsNotNull(reloadedEntity);
AssertAreEqual(entity, reloadedEntity);
}
[Test]
public virtual void DeleteEntity_EntityWasDeleted()
{
var entity = BuildEntity();
InsertEntity(entity);
DeleteEntity(entity);
Assert.IsNull(session.Get<TEntity>(entity.Id));
}
protected virtual void InsertEntity(TEntity entity)
{
session.Save(entity);
session.Flush();
}
protected virtual void UpdateEntity(TEntity entity)
{
session.Update(entity);
session.Flush();
}
protected virtual void DeleteEntity(TEntity entity)
{
session.Delete(entity);
session.Flush();
}
protected abstract TEntity BuildEntity();
protected abstract void ModifyEntity(TEntity entity);
protected abstract void AssertAreEqual(TEntity expectedEntity, TEntity actualEntity);
protected abstract void AssertValidId(TEntity entity);
}
Simply inherit from this class, implement the BuildEntity, ModifyEntity, AssertAreEqual and AssertValidId methods and that’s it. Those methods are usually pretty simple. In BuildEntity you just create an unpersisted entity and assign values to the properties, in ModifyEntity you modify the properties, and in AssertAreEqual you compare the properties of both instances. In AssertValidId, you make sure that the ID value is ok (depending on your identifier strategy).
This is good for regular CRUD operations, though we typically add extra tests when we want to test cascades or one-to-many associations mapped with inverse=”true”.
Pingback: Reflective Perspective - Chris Alcock » The Morning Brew #493
Pingback: Ere Thrice the Sun Done Salutation to the Dawn « Search And Destroy