lunes, 11 de junio de 2007

Testing de Repositorios

Bueno, despues de algunos dias amenazando con que iba a hacer este post me digne a escribirlo...

Cada vez que empiezo con un nuevo proyecto me pregunto como testear mejor los repositorios, o al menos de una formas mas sencilla. Esta vez hice 2 clases bases para eso:

- BaseMemoryRepository.cs: Es una clase abstracta que tiene 2 tipos genericos (). El TEntity indica cual es la clase que se debe persistir, por ejemplo puede ser un simple Customer, el TIdentity es el tipo de Id.

Si el TIdentity especificado es del tipo numerico (Int16, 32 ó 64) o GUID, la misma clase se encarga de la generacion automatica, pero si se quiere usar algo muy complicado la unica solucion es hacer un override del metodo object GetNextId().

De esta forma, un repositorio simple quedaria asi:


public class CustomerRepository : BaseMemoryRepository,
ICustomerRepository
{
protected override int GetEntityId(Customer ent)
{
return ent.Id;
}

protected override int GetEntityId(Customer ent)
{
return ent.Id;
}

protected override void SetEntityId(Customer ent, int ident)
{
ent.Id = ident;
}
}

- CustomerRepositoryTests.cs: Esta clase es un poco mas compleja de usar que la anterior. Provee la funcionalidad para realizar CRUD todo junto, si bien no es lo mejor que se puede hacer en TDD, normalmente testear las operaciones basicas es resuelto de la misma forma. Por ejemplo si se usa un ORM lo mas probable es que funciona todo o no funciona nada.
Es importante implementar 4 metodos en esta clase, estos se encargan de:
- Crear un objeto de Testing
- Devolver el Id de una entidad, necesario por el desconocimiento de cual es la propiedad Id de un objeto
- Validar si el id de un objeto es valido; una vez que se crea un objeto se espera que un nuevo Id se le asigne, por eso con validar solamente que sea mayor a 0 alcanza en la mayoria de los casos.
- El Test :) (que tiene que llamar a base.BasicOperationsTest())

Aca va un ejemplo:

[TestFixture]
public class CustomerRepositoryTests : BaseRepositoryTests
{
public override void BuildTestEntity(out Customer e)
{
// Tengo que crear un nuevo Customer y configurar
// informacion de prueba
e = new Customer();
e.Name = "Name";
e.Gender = Gender.Male;
e.BornDate = DateTime.Now;
}

public override object GetEntityId(Customer ent)
{
return ent.Id;
}

public override bool IsValidEntityId(Customer entity)
{
// Una validacion simple
return entity.Id > 0;
}

[Test]
public override void BasicOperationsTest()
{
// Aca hago el trabajo real!
base.BasicOperationsTest();
}
}
Y listo, una vez que implementamos esas 2 clases por repositorio ya tenemos todos los test simples...

El codigo completo con los 2 ejemplos de implementacion los pueden bajar de acá o de acá

No hay comentarios: