Pergunta

Depois de vários anos seguindo a péssima prática proferida de 'arquitetos' no meu local de trabalho e pensando que deve haver uma maneira melhor, eu tenho lido recentemente em torno de TDD e DDD e acho que os princípios e práticas seriam um Ótimo ajuste para a complexidade do software que escrevemos.

No entanto, muitas das amostras de TDD que eu vi chamam um método no objeto de domínio e, em seguida, testam as propriedades do objeto para garantir que o comportamento seja executado corretamente.

Por outro lado, várias pessoas respeitadas na indústria (Greg Young mais visivelmente, com suas palestras sobre o CQRS), definem totalmente cada objeto de domínio, removendo todos os 'Getters'.

Minha pergunta, portanto, é: como se teste a funcionalidade de um objeto de domínio se for proibido recuperar seu estado?

Acredito que estou perdendo algo fundamental, então fique à vontade para me chamar de idiota e me esclarecer - qualquer orientação seria muito apreciada.

Foi útil?

Solução

O que você está descrevendo é Verificação do estado onde você afirma sobre o estado do objeto de domínio. Há um ramo do TDD que é chamado Verificação de comportamento Isso utiliza objetos simulados.

A verificação de comportamento permite especificar quais métodos devem ser chamados e, se desejar, quais métodos não são chamados.

Veja este artigo de Martin Fowler para obter mais detalhes: Mochinhas não são stubs.

Outras dicas

Ok, esta resposta é um ano tarde demais ;-)

Mas quando você deseja testar os modelos CQRS, pode fazer afirmações nos eventos de domínio demitidos, em vez de afirmações no estado da entidade.

Por exemplo, se você deseja testar se a chamada: client.rename ("foo") resultar no comportamento correto.

Em vez de testar se o cliente.name é igual a "foo", você prefere testar se existe um evento de nome do alfândega pendente com o valor "foo" em sua loja de eventos pendentes. (em sua lista de eventos Uow ou em sua entidade, dependendo da implementação)

Se você realmente chegar ao ponto de proibir a recuperação de estado, estará limitado a testes comportamentais, provavelmente por meio de uma estrutura de zombaria, como o TypeMock, que tem o poder de rastrear o comportamento do seu objeto. Se você é capaz de fazer puro BDD, teoricamente, poderá afirmar a correção de todo o seu sistema, apenas pela maneira como ele está se comportando.

Na prática, achei o BDD mais quebradiço em muitos casos do que apenas testes com estado. Embora algumas pessoas possam pedir uma certa teoria, ela só funciona se funcionar para você. Os testes estatais ainda representam 90% de todos os testes de unidade que escrevemos e estamos bem cientes do BDD em nossa equipe.

Faça o que for melhor para você.

Algumas coisas.

Primeiro, quando você faz coisas como TDD para tornar seu código testável, você acaba com aula menor. Se você tem uma aula com muitas propriedades privadas, não pode inspecionar, há uma boa chance de que ele possa ser dividido em várias classes e tornado mais testável.

Segundo, a arquitetura do Oldschool OO tenta tornar o software seguro usando salvaguardas de idiomas para impedir que as coisas sejam acessíveis. Uma arquitetura TDD torna o software mais robusto ao escrever testes que verificam o que o código realmente faz, colocando menos ênfase no uso de construções de idiomas para garantir o que o programa não faz.

Por fim, verificar uma propriedade não é a única maneira de validar o código fez o que deveria fazer. O livro Xunit Design Patterns documenta outras abordagens aqui: http://xunitpatterns.com/result%20Verification%20Patterns.html

Eu chamo os métodos de entrada pública de um sistema (ou seja, pressiono os dados de entrada no sistema) e depois recebo (e afirmo) a saída do sistema. Não estou testando o estado interno do sistema, mas seu comportamento público/visível: Deveria um teste de implementação interna ou apenas testar o comportamento público?

O que você mencionou é chamado de teste de estado. Também há testes de comportamento. As técnicas usadas para isso são injeção de dependência, inversão de controle e zombaria:

Todos os efeitos colaterais da sua classe são implementados como invocações de métodos em suas "dependências" - ou seja, objetos fornecidos de fora, geralmente no construtor. Então, no seu teste unitário, você fornece um objeto falso em vez de um real. O objeto falso pode se lembrar se seu método 'foi chamado, e é isso que você afirma em seu teste.

Existe um número de estruturas de zombaria que automatizam a criação de objetos simulados, gerando dinamicamente classes que implementam uma determinada interface. Os mais populares são rinocerontes. Mocks e MOQ.

Ei, Justin, como você, eu estava pensando recentemente em adicionar getters ao meu objeto de domínio somente de gravação por causa dos testes de unidade, mas agora estou convencido de que estava errado. Supondo que você tenha comprado a idéia de um domínio somente de gravação em primeiro lugar, se você tiver getters, está pedindo problemas. O princípio do domínio somente de gravação desejaria que você demitisse um evento do seu objeto de domínio ou leia a partir de uma projeção que seu objeto de domínio escreveu, ou algo assim. Depois de expõe os getters, você está começando a expor a "forma" do objeto e, como Greg Young diz, "os objetos de domínio têm comportamento, não moldam".

Dito isto, estou lutando com a mesma pergunta ... como você testa uma unidade de um objeto de domínio somente de gravação? Aqui está o meu plano atual: estou pensando em fazer meu objeto de domínio disparar um evento de domínio dizendo "Essas propriedades mudaram" e, no meu teste de unidade, vou me inscrever antes de enviar o "EditCommand". Confira a postagem de Udi Dahan nos eventos de domínio aqui, e também veja O que Eric Evans diz sobre eventos de domínio.

Eu estava me perguntando a mesma coisa até que finalmente tropecei nos documentos a seguir. Eu achei que eles são ótimos iniciadores sobre a verificação de comportamento, especialmente o primeiro, fornecendo -me vários "momentos AHA":

  1. Usando zombarias e testes para projetar objetos baseados em funções
  2. Papéis simulados, não objetos
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top