Unit test of implementations of a generic class

4

Suppose we have the following Interface:

public interface ICRUDService<T>
{
    T Create(T entity);            
}

Abstract Implementation:

public abstract class CrudService<T> : ICRUDService<T>        
{         
    IRepository repositorio;      
    public EntityService(IRepository rep)
    {
        repositorio= rep;            
    }  

    public virtual T Create(T entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity ");
        }
        repositorio.Add(instance);           
        return entity;
    }                  
}

For each object in my domain (Ex: Person, Car, Animal) will implement a service:

  public class PessoaService :CrudService<Model.Pessoa>{
    IRepository repositorio;      
    public PessoaService (IRepository repo):base(repo)
    {
        repositorio= repo;
    }
    public void MetodoPersonalizadoServicoPessoa(){
         var oi = "oi";
    }         
   } 

  public class CarroService :CrudService<Model.Carro>{
    IRepository repositorio;      
    public CarroService (IRepository repo):base(repo)
    {
        repositorio= repo;
    }
    public void MetodoPersonalizadoServicoCarro(){
         var oi = "oi2";
    }         
   }

-What is the best way to test each CrudService implementation?

- For each implementation should I repeat the test of the Create method of the abstract class?

-Is there any way to create a generic abstract test that automatically tests the Create method on all classes that implement it?

    
asked by anonymous 06.03.2015 / 00:10

1 answer

3

What is the best way to test each CrudService implementation?

Creating an explicit test for each implementation.

You can test the virtual methods of the abstract class by creating in the test code an inheritance of this class and testing this inherited class. It is important to do this to ensure that virtual methods that are not overwritten by any concrete implementation are also tested.

For each implementation should I repeat the test of the Create method of the abstract class?

You should repeat the test only for concrete implementations that override the virtual method of the abstract parent class.

You do not need to repeat the test when the virtual method is not overwritten otherwise you will be testing the same code twice.

Is there any way to create a generic abstract test that automatically tests the Create method on all classes that implement it?

If you are referring to using some reflection type magic to identify all concrete implementations and exit testing ... Not a good idea. Each test should be expressive, indicating very clearly what is being tested and for what purpose.

If you use reflection to identify what to test, there may come a time when this search will find nothing, and the test will continue to "dirty" your test suite and eventually cause confusion: CRUD services appear to be being tested and they are not.

Inheritance and testing

Avoid using inheritance only for code reuse.

Note how many inheritance doubts have arisen, which inheritance adds a lot of complexity, and breaks the abstraction (see that you need to know whether or not a class overrides a method of the parent class to know how to test it or to avoid repeated testing).

The use of inheritance in your example is not bringing any benefit.

    
01.04.2015 / 18:12