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.