Mock não é uma muleta, o mock é uma especificação

Entre os muitos pseudo-ides que orbitam os TDDs, há um pouco de desconsideração das duplas de teste, principalmente relacionadas aos seus nomes ridículos.

Eles os chamariam de alguma forma com orgulho, caso contrário, mok, stub, fake - um sentimento de que realmente não perdemos nada se não o usarmos. (Ao contrário de "testes de integração" e "dependências reais").

No entanto, você pode alterar o ponto de vista. No final, o mock não apenas apoia e não apoia muito o componente dependente, mas especifica o comportamento da dependência. E a implementação “real” é uma certa encarnação atual, possivelmente errônea, da nossa orgulhosa ideia.

Nesse sentido, toda vez que escrevemos

when(mockDependency.method(inputValue)).thenReturn(returnValue) ,

documentamos algum comportamento de componente.

Portanto, existem várias consequências.

Objetos simulados estão intimamente conectados às especificações reais do teste, tanto no vocabulário quanto no significado. Tanto esse como outro nos concentram em requisitos e cenários, mas não nos recursos da implementação atual.

O fato de que declarações sobre um componente a serem molhadas ao usar estruturas como o Mockito são um pouco perturbadoras para nós estão espalhadas entre as classes de clientes, e é difícil acompanhá-las. Nesse sentido, classes descendentes explícitas com comportamento predefinido são preferíveis a zombarias como o Mockito, porque permitem encapsular scripts e visualizá-los rapidamente.

Portanto, as classes de script ValidOrderProviderStub, ExpiredOrderProviderStub, InvalidOrderIdException_OrderProviderStub, OnlyOnceOrderProvider e assim por diante, que podem estar no mesmo pacote e usadas por todos os testes ao mesmo tempo, são adicionadas a cada classe OrderProvider.

Isso inclui classes de Spy fáceis de implementar.

Além disso, essa abordagem é mais rápida de executar e funciona sem o uso de reflexão.

Assim, ao ler o código, podemos fazer uma convenção de que a presença de mok confirma a possibilidade de um script, e sua ausência proíbe a existência de tal script. Se proibimos as classes de cliente de escrever expectativas de mockito, na busca por NullOrderProvider, verifica-se que não há simulação adequada, porque nulo nunca retorna e, portanto, não faz sentido testar esse cenário.

Se mok é uma especificação, mok é um reflexo de nossos planos para um componente, e eles podem e devem ser escritos antes da implementação.

Se um mok é uma especificação, é hierárquico e reflete o comportamento do componente, dependendo de determinadas condições.

Assim, nosso moki pode se multiplicar demais: moki incondicional sempre retornando o mesmo, assim como moki com condições internas, como forIdOne_returningOne_forIdTwo_ReturningTwo_OrderProvider. A última enumeração e você só precisam criar um FakeOrderProvider com o comportamento apropriado, que deve ser sincronizado com a implementação real.

Portanto, se um mok é uma especificação de um determinado comportamento, a implementação de um componente nada mais é do que sincronizar o comportamento de um componente com seus moks.

E esse, talvez, seja o principal argumento contra os mobs - a necessidade de sincronizar seu comportamento com a implementação real atual, falaremos sobre isso separadamente da próxima vez.

Source: https://habr.com/ru/post/pt474484/


All Articles