Escrevi alguns testes de unidade para algum código novo no trabalho e o enviei para uma revisão de código. Um de meus colegas de trabalho fez um comentário sobre por que eu estava colocando variáveis usadas em vários desses testes fora do escopo do teste.
O código que eu publiquei era essencialmente
import org.junit.Test;
public class FooUnitTests {
@Test
public void testConstructorWithValidName() {
new Foo(VALID_NAME);
}
@Test(expected = IllegalArgumentException.class)
public void testConstructorWithNullName() {
new Foo(null);
}
@Test(expected = IllegalArgumentException.class)
public void testConstructorWithZeroLengthName() {
new Foo("");
}
@Test(expected = IllegalArgumentException.class)
public void testConstructorWithLeadingAndTrailingWhitespaceInName() {
final String name = " " + VALID_NAME + " ";
final Foo foo = new Foo(name);
assertThat(foo.getName(), is(equalTo(VALID_NAME)));
}
private static final String VALID_NAME = "name";
}
Suas mudanças propostas foram essencialmente
import org.junit.Test;
public class FooUnitTests {
@Test
public void testConstructorWithValidName() {
final String name = "name";
final Foo foo = new Foo(name);
}
@Test(expected = IllegalArgumentException.class)
public void testConstructorWithNullName() {
final String name = null;
final Foo foo = new Foo(name);
}
@Test(expected = IllegalArgumentException.class)
public void testConstructorWithZeroLengthName() {
final String name = "";
final Foo foo = new Foo(name);
}
@Test(expected = IllegalArgumentException.class)
public void testConstructorWithLeadingAndTrailingWhitespaceInName() {
final String name = " name ";
final Foo foo = new Foo(name);
final String actual = foo.getName();
final String expected = "name";
assertThat(actual, is(equalTo(expected)));
}
}
Onde tudo o que é necessário dentro do escopo do teste é definido dentro do escopo do teste.
Algumas das vantagens que ele argumentou foram
- Cada teste é independente.
- Cada teste pode ser executado isoladamente ou em agregação, com o mesmo resultado.
- O revisor não precisa rolar para onde esses parâmetros forem declarados para procurar qual é o valor.
Algumas das desvantagens de seu método que eu argumentei foram
- Aumenta a duplicação de código
- Pode adicionar ruído à mente dos revisores se houver vários testes semelhantes com valores diferentes definidos (por exemplo, teste com
doFoo(bar)
resultados em um valor, enquanto a mesma chamada tem um resultado diferente porquebar
é definido de maneira diferente nesse método).
Além da convenção, existem outras vantagens / desvantagens de usar um dos métodos sobre o outro?