Dia bom! O artigo será sobre um ponto completamente insignificante na codificação.
Por exemplo, muitos dos meus colegas disseram - Doch, das ist ganz normal! "E, o que, todas as regras, eu encontrei algo para reclamar!" Mas mesmo assim.
Existem algumas coisas sobre a codificação que me irritam. Bem, na verdade não alguns. :), quanto mais velho fico, mais e mais coisas assim, o personagem não melhora. Mas no topo - quando os desenvolvedores escrevem testes para métodos privados. Ah não! Quando, por causa disso, eles removem a palavra privado do método e o método se torna privado do pacote.
Portanto, você revisa uma classe como esta, linhas em 3K, escrita nas melhores tradições de programação procedural, e há 10 métodos públicos, 10 privados e mais 15 privados de pacote. E não ouvimos falar sobre interfaces - este é um serviço, vamos injetá-lo assim! Ok, você pensa, agora vamos arregaçar as mangas, vamos mover todos os métodos públicos para a interface, helper-s, eles em um pacote separado - em resumo, vamos cortar essa loucura em pedaços de acordo com o SRP. Mas então você descobre que os métodos de pacote privado têm se afastado de outros lugares por um longo tempo. Portanto, temos todas as classes em um pacote despejado! Se algo pode ser mal utilizado, com certeza o será, como dizem.
Sim, todos sabem, você não precisa escrever testes para métodos privados; se você fizer isso, algo está errado com o design e assim por diante. Mas, droga, as pessoas fazem isso de qualquer maneira, e devo dizer, não sem razão. Imagine que a classe acima tenha cobertura de teste zero. E você precisa refatorar. É assim que os métodos de pacote privado entram. Mas como podemos ser - eles cortaram o Whitebox do Mockito, é claro, ele permaneceu no PowerMock , mas por causa disso, arraste o PowerMock para o projeto, e a sintaxe não é melhor do que uma chamada direta por meio de reflexão. Você pode, é claro, escrever sua própria bicicleta, mas ... E então não funciona assim.
Mas imagine que temos uma interface para acessar elementos privados de uma classe - métodos, campos. Que diabo, você diz, o cara está trabalhando duro. Mas assim:
Existe uma classe:
public class ObjectWithPrivates {
private final AtomicInteger count = new AtomicInteger(0);
private String name;
private String methodToTest(String in) {
return name + in + count.incrementAndGet();
}
}
Teste:
interface TestPrivates {
void setName(String name);
String methodToTest(String in);
AtomicInteger getCount();
}
@Test
void testPrivates() {
ObjectWithPrivates obj = new ObjectWithPrivates();
TestPrivates objWithPrivates = API.lookupPrivatesIn(obj)
.usingInterface(TestPrivates.class);
objWithPrivates.setName("Andromeda");
String in = objWithPrivates.methodToTest("in");
AtomicInteger count = objWithPrivates.getCount();
Assertions.assertEquals("Andromedain1", in);
Assertions.assertEquals(1, count.get());
}
Como você pode ver, usando a interface, podemos buscar métodos privados e acessar campos privados. Bem, você pode dizer imediatamente pelo código o que está acontecendo. Tenha em mente que todas as manipulações ocorrem com obj e você pode, por exemplo, definir todos os campos privados de obj e então puxar o método público.
Você pode acessar os campos / métodos privados da classe pai:
TestPrivates accessToPrivates = API.lookupPrivatesIn(obj) .lookupInSuperclass() .usingInterface(TestPrivates.class);
Ou você pode puxar métodos estáticos:
TestPrivates accessToPrivates = lookupPrivatesIn(SomePOJOClass.class) .usingInterface(TestPrivates.class); accessToPrivate.someStaticPrivateMethod();
Ou você pode criar um objeto por meio do construtor privado.
Sob o capô, há reflexão padrão e proxy dinâmico, sem dependências adicionais.
Aqui está um link para o projeto testprivates . Use apenas para testes.
Tudo com a vinda, não adoeça!