Não faça testes de unidade de código de terceiros

Ao escrever testes de unidade, certifique-se de que os testes que você está escrevendo exercitem o mínimo de código de terceiros possível.

  • Você não se beneficia da cobertura de teste
  • A configuração, desmontagem e asserções confundem suas classes de teste
  • Todas as afirmações bem-sucedidas podem fazer você pensar que escreveu um ótimo teste quando tudo o que você realmente fez foi confirmar se o JDK / lib funciona como deveria.
    • Se você não acredita que o código de terceiros está correto, por que o está usando?

tempo de exemplo inventado!

Imagine um wrapper de mapa que adiciona segurança de tipo a um HashMap. Você pode ter o seguinte

import java.util.HashMap;

public class IntegerMap extends HashMap
{
public Integer put(Object k, Integer v)
{
return (Integer) super.put(k, v);
}

@Override
public Integer get(Object key)
{
return (Integer) super.get(key);
}
}

Como eu disse, planejado …

Você poderia facilmente terminar com o seguinte teste de unidade

public class TestIntegerMap
{
ensureMapEmptyAfterCreate
()
ensureMapEmptyAfterClear
()
ensureMapNotEmptyAfterAdd
()
ensureMapEmptyAfterClearAddRemove
()
.....
}

Embora todos esses testes confirmem que IntegerMap se comporta conforme o esperado, quase tudo é redundante. O HashMap já começa vazio quando você o cria, portanto, o IntegerMap também começará. Chamadas subsequentes para get () com o mesmo argumento retornarão o mesmo valor. Todos esses testes parecem ótimos e fornecem muitas linhas verdes em seus relatórios de teste, mas eles apenas testam o HashMap e não provam nada sobre o seu código.

O que IntegerMap realmente faz? Ele simplesmente entrega argumentos para o HashMap, enquanto restringe o tipo de alguns argumentos e valores de retorno. Portanto, o que realmente vale a pena testar são as interações com o HashMap.

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestIntegerMap {
private static final Object TEST_KEY = new Object();
private static final Integer TEST_VALUE = new Integer(3);
private static IntegerMap mapToTest;

@Before
public void setUp() throws Exception {
mapToTest
= new IntegerMap();
}

@After
public void tearDown() throws Exception {
mapToTest
= null;
}

@Test
public void testPutGet() {
mapToTest
.put(TEST_KEY, TEST_VALUE);
Integer returned = mapToTest.get(TEST_KEY);
assertEquals
("Object returned should be the object inserted", TEST_VALUE, returned);
}
}

É isso aí. Um teste cobre todo o seu código. Sem desordem, sem esforço desperdiçado. Todo o resto pode ser assumido por outra pessoa.

Se você tiver um código de terceiros de qualidade desconhecida, escreva um conjunto de testes antes de usá-lo. Se você precisar verificar se está usando uma biblioteca corretamente, escreva alguns testes de integração para confirmá-lo. Apenas não incorpore esses testes com os testes de unidade para seu projeto.