Sunday, September 18, 2016

Abstract: How to write a unit test that is able to instantiate a class using a constructor declared as private. By doing it, cobertura will include the test into its coverage report, helping you to achieve code coverage requirements.

É ponto pacífico que todo código deveria possuir testes unitários. Já para o que precisa ser testado e qual e extensão dos testes, não se tem uma regra clara e sempre gera discussões. Eu em geral busco 100% de cobertura.

Segundo algumas regras de estilo, "esconder" o construtor é uma boa prática e essa prática faz parte do manual de codificação para a empresa em que trabalho. O problema é que o cobertura (sistema que mede o percentual de testes que cobrem um código) não entende isso, e ao analisar o código fonte, acusa que faltam testes para o construtor privado. Com isso, o percentual de cobertura diminui.

Isso não é um problema, na medida em que se você construiu os testes para os métodos estáticos e eles estão funcionando, o construtor também irá funcionar. Mas, eu tenho TOC e depois de dar duro construindo testes, gosto de ver o relatório apontando 100%. Satisfação pessoal. Simples assim.

Então resolvi pesquisar se existiria uma maneira de fazer o cobertura entender que o construtor foi testado e encontrei um jeito legal de se fazer isso. Basta criar um teste unitário conforme exemplificado abaixo. Por reflexão ele irá instanciar a classe usando o método privado, e com isso, satisfazer o cobertura.

@Test
public void testPrivateConstructor() throws Exception {
   Constructor[] constructors = MyUtilityClass.class.getDeclaredConstructors();

// Only the private constructor
assertTrue(constructors.lenght == 1);

// And it should be private

assertFalse(constructors[0].isAccessible());

   constructors[0].setAccessible(true);
   constructors[0].newInstance((Object[])null);
}




No comments:

Post a Comment