Versão ALPHA! Este artigo está em versão 'Alpha' e, portanto, não foi ainda revisado corretamente

Entidades em hierarquia - Teste de ConsultaDelegate

Introdução

É de suma importância saber o tipo de relacionamento que uma entidade possui ao implementar a consulta da mesma, neste caso entenda relacionamento em como a entidade esta estruturada na aplicação, se extende uma super entidade ( herança ) ou se tem uma entidade ( composição ), neste artigo será abordada a implementação de consultas com entidades se relacionando através do mecanismo de herança e que utilizam o relacionamento Single Table no banco de dados.

Não repita herança para resolver este tipo de problema

Evite re-utilizar a herança para resolver este problema, deixe-a apenas na modelagem das entidades, dê preferência à composição, abaixo em nosso exemplo utilizaremos as entidades Empregado(superclasse) e Gerente (Subclasse).

Implementando o esqueleto do teste

Antes de começar a implementar a consulta das entidades é de suma importância começar pelo teste da consulta delegate já que a mesma será utilizada na consulta de Gerente, atenção ao teste:

@Test
@Guice(modules = { ModuloDeTesteEmpregado.class })
public class TesteDeConsultaDeEmpregadoDelegate {

  @Inject
  private ConsultaDeEmpregadoDelegate consulta;

  @Inject
  private DBUnit dbUnit;

  @BeforeClass
  public void prepararDBUnit() {
    dbUnit.loadDefaultDataSet();
  }

  public void listagem_caso_gerente() {
    FakeRequestWrapper wrapper = new FakeRequestWrapper();

    List<Empregado> contra = contra(1, 2, 3, 4);
    List<String> prova = transform(contra, new GerenteToString());

    List<ConsultaDeEmpregadoDTO> list = consulta.list(wrapper, "G");
    List<String> res = transform(list, new DtoToString());

    assertThat(res, equalTo(prova));
  }
	
}

Seguindo às praticas do TDD, crie a consulta e a interface ConsultaDeEmpregadoDTO, mas não adicione nenhuma linha de código a interface, quanto a Consulta adicione o método list que é chamado no teste.

class ConsultaDeEmpregadoDelegate {

  private final Provider<NativeSql> sqlProvider;

  @Inject
  public ConsultaDeEmpregadoDelegate(Provider<NativeSql> sqlProvider) {
    this.sqlProvider = sqlProvider;
  }

  public List<ConsultaDeEmpregadoDTO> list(RequestWrapper wrapper, String discriminador) {
    return null;
  }

Importante: ao implementar uma consulta deste tipo (delegate) seu modificador de acesso sempre deve ser default.

A respeito do método contra e da propriedade buscarEmpregado

Estes são elementos muito importantes dos testes pois, são responsáveis em capturar os registros existentes de Empregado que estão no bd e adicioná-los em uma estrutura do tipo List, para verificar a funcionalidade da consulta, facilitando e muito a realização de incontáveis asserts no teste da consulta

Criando a classe TesteDeConsultaDeEmpregadoBuscador

Crie este utilitário no mesmo pacote que seu teste de consulta delegate, ela tem como objetivo servir o método contra, fornecendo uma lista de Empregados.

class TesteDeConsultaDeEmpregadoBuscador {

  private final BuscarEmpregado buscarEmpregado;

  @Inject
  public TesteDeConsultaDeEmpregadoBuscador(BuscarEmpregado buscarEmpregado) {
    this.buscarEmpregado = buscarEmpregado;
  }

  public List<Empregado> contra(Integer... ids) {
    ImmutableList<Integer> _ids = ImmutableList.copyOf(ids);
    Iterable<Empregado> Empregados = Iterables.transform(_ids, new IdLoader());
    Iterable<Empregado> notNull = Iterables.filter(Empregados, Predicates.notNull());
    ArrayList<Empregado> mutable = newArrayList(notNull);
    Collections.sort(mutable, new OrdenacaoPadraoDeEmpregado());
    return ImmutableList.copyOf(mutable);
  }

  class OrdenacaoPadraoDeEmpregado implements Comparator<Empregado> {
    @Override
    public int compare(Empregado o1, Empregado o2) {
      return ComparisonChain.start()
          .compare(o1.getNome().toLowerCase(), o2.getNome().toLowerCase())
          .result();
    }
}	  

  private class IdLoader implements Function<Integer, Empregado> {
    @Override
    public Empregado apply(Integer id) {
      return buscarEmpregado.porId(id);
    }
  }

}

Criando o método contra

Este método retornará a lista de empregados utilizada nos asserts acima, dado uma série de ids, o mesmo retorna em uma lista todos os empregados que correspondem aos ids fornecidos no método

private List<Empregados> contra(Integer... ids) {
  return buscarEmpregado.contra(ids);
}

Não se esqueça de declarar o TesteDeConsultaDeEmpregadoBuscador em seu teste, sempre declare novas propriedades abaixo de DBUnit, com exceção do que está sendo testado

@Inject
private DBUnit dbUnit;
@Inject
TesteDeConsultaDeEmpregadoBuscador buscarEmpregado;

Implementando a função DtoToString

No teste implemente a função DtoToString que deverá realizar um toString com todas as propriedades de Empregado, atente a sua implementação

private class DtoToString implements Function<ConsultaDeEmpregadoDelegateDTO, String> {
  @Override
  public String apply(ConsultaDeEmpregadoDelegateDTO input) {
    return Objects.toStringHelper("")
      .addValue(input.getId())
      .addValue(input.getNome())
      .addValue(input.getDepartamento())
      .addValue(input.getArea())
      .toString();
  }
}	  

Enquanto implementa a função adicione os métodos de Empregado na interface ConsultaDeEmpregadoDelegateDTO.

Implementando a classe GerenteToString

Crie a classe GerenteToString, que será responsável em facilitar os futuros asserts realizados no teste da consulta.

class GerenteToString implements Function<Gerente, String> {
  @Override
  public String apply(Empregado empregado) {
    Gerente input = (Gerente) empregado;
    return Objects.toStringHelper("")
      .addValue(input.getId())
      .addValue(input.getNome())
      .addValue(input.getDepartamento())
      .addValue(null)
      .toString();
  }
}

Atenção : não se esqueça de realizar o casting para que o Empregado em questão seja um Gerente, assim sera possível adicionar as propriedades de Gerente na função acima.

Adicione apenas as propriedades de Gerente nesta função, marque os demais campos como null, pois na hora de realizar o assert devemos ter certeza de que um Gerente não tenha propriedades de outra entidade

Finalizando o teste

No final o teste do processo o teste estará semelhante ao seguinte bloco de código

@Test
@Guice(modules = { ModuloDeTesteEmpregado.class })
public class TesteDeConsultaDeEmpregadoDelegate {

  @Inject
  private ConsultaDeEmpregadoDelegate consulta;

  @Inject
  private DBUnit dbUnit;
  @Inject
  TesteDeConsultaDeEmpregadoBuscador buscarEmpregado;

  @BeforeClass
  public void prepararDBUnit() {
    dbUnit.loadDefaultDataSet();
  }

  public void listagem_caso_gerente() {
    FakeRequestWrapper wrapper = new FakeRequestWrapper();

    List<Empregado> contra = contra(1, 2, 3, 4);
    List<String> prova = transform(contra, new GerenteToString());

    List<ConsultaDeEmpregadoDTO> list = consulta.list(wrapper, "G");
    List<String> res = transform(list, new DtoToString());

    assertThat(res, equalTo(prova));
  }
private List contra(Integer... ids) {
    return buscarEmpregado.contra(ids);
 	  }
  
  private class DtoToString implements Function<ConsultaDeEmpregadoDelegateDTO, String> {
    @Override
    public String apply(ConsultaDeEmpregadoDelegateDTO input) {
      return Objects.toStringHelper("")
        .addValue(input.getId())
        .addValue(input.getNome())
        .addValue(input.getDepartamento())
        .addValue(input.getArea())
        .toString();
    }
  }

}

 
 

objectos, Fábrica de Software LTDA

  • R. Demóstenes, 627. cj 123
  • 04614-013 - Campo Belo
  • São Paulo - SP - Brasil
  • +55 11 5093-8640
  • +55 11 2359-8699
  • contato@objectos.com.br