testing - test - mocks aren t stubs




Qual é a diferença entre um mock & stub? (20)

Eu li vários artigos sobre zombaria vs stub no teste, incluindo Mocks de Martin Fowler não são stubs , mas ainda não entendi a diferença.


Prefácio

Existem várias definições de objetos, que não são reais. O termo geral é duplo teste . Este termo engloba: falso , falso , esboço , simulado .

Referência

De acordo com o artigo de Martin Fowler :

  • Objetos falsos são passados, mas nunca são usados. Geralmente eles são usados ​​apenas para preencher listas de parâmetros.
  • Objetos falsos , na verdade, têm implementações de trabalho, mas geralmente usam algum atalho que os torna não adequados para produção (um banco de dados de memória é um bom exemplo).
  • Os stubs fornecem respostas prontas às chamadas feitas durante o teste, geralmente não respondendo a nada do que está programado para o teste. Os stubs também podem registrar informações sobre chamadas, como um stub de gateway de email que lembra as mensagens que ele enviou, ou talvez apenas quantas mensagens ele 'enviou'.
  • Mocks são o que estamos falando aqui: objetos pré-programados com expectativas que formam uma especificação das chamadas que eles devem receber.

Estilo

Mocks vs Stubs = Teste comportamental vs teste estatal

Princípio

De acordo com o princípio do teste apenas uma coisa por teste , pode haver vários stubs em um teste, mas geralmente há apenas um mock.

Ciclo da vida

Ciclo de vida de teste com stubs:

  1. Setup - Prepara o objeto que está sendo testado e seus stubs colaboradores.
  2. Exercício - teste a funcionalidade.
  3. Verificar estado - use afirmações para verificar o estado do objeto.
  4. Teardown - Limpe os recursos.

Teste o ciclo de vida com mocks:

  1. Dados de configuração - Prepara o objeto que está sendo testado.
  2. Exigências de configuração - Prepare as expectativas em simulação que estão sendo usadas pelo objeto principal.
  3. Exercício - teste a funcionalidade.
  4. Verificar expectativas - Verifique se os métodos corretos foram invocados no simulado.
  5. Verificar estado - use afirmações para verificar o estado do objeto.
  6. Teardown - Limpe os recursos.

Resumo

Os testes de zombaria e stubs dão uma resposta para a pergunta: Qual é o resultado?

Testes com zombarias também estão interessados ​​em: Como o resultado foi alcançado?


A Mock está apenas testando o comportamento, certificando-se de que certos métodos sejam chamados. Um Stub é uma versão testável (per se) de um objeto específico.

O que você quer dizer com um jeito da Apple?


Desde o papel Mock Roles, não Objects , pelos desenvolvedores do jMock:

Stubs são implementações falsas de código de produção que retornam resultados enlatados. Mock Objects atuam como stubs, mas também incluem asserções para instrumentar as interações do objeto alvo com seus vizinhos.

Então, as principais diferenças são:

  • as expectativas definidas nos stubs são geralmente genéricas, enquanto as expectativas definidas nos mocks podem ser mais "inteligentes" (por exemplo, retornar isso na primeira chamada, isso na segunda, etc.).
  • Os stubs são usados ​​principalmente para configurar entradas indiretas do SUT , enquanto os mocks podem ser usados ​​para testar tanto entradas indiretas quanto saídas indiretas do SUT.

Resumindo, ao mesmo tempo tentando dispersar a confusão do título do artigo de Fowler : mocks são stubs, mas eles não são apenas stubs .


Este slide explica as principais diferenças muito boas.

* De CSE 403 Lição 16, Universidade de Washington (slide criado por "Marty Stepp")


Eu acho que a resposta mais simples e clara sobre esta questão é dada por Roy Osherove em seu livro The art of Unit Testing (página 85).

A maneira mais fácil de saber que estamos lidando com um stub é notar que o stub nunca pode falhar no teste. O afirma que os usos de teste são sempre contra a classe em teste.

Por outro lado, o teste usará um objeto simulado para verificar se o teste falhou ou não. [...]

Novamente, o objeto mock é o objeto que usamos para ver se o teste falhou ou não.

Isso significa que se você está fazendo afirmações contra o falso, significa que você está usando o falso como um mock, se você estiver usando o fake apenas para executar o teste sem asserção sobre ele, você está usando o falso como um stub.


Eu gosto da explicação dada por Roy Osherove [link de vídeo] .

Cada classe ou objeto criado é um falso. É uma simulação se você verificar as chamadas contra ela. Caso contrário, é um esboço.


Lendo todas as explicações acima, deixe-me tentar condensar:

  • Stub : um trecho de código falso que permite que o teste seja executado, mas você não se importa com o que acontece com ele.
  • Mock : um pedaço de código falso, que você VERIFY é chamado corretamente como parte do teste.
  • Spy : um código falso, que intercepta algumas chamadas para um trecho real de código, permitindo que você verifique as chamadas sem substituir todo o objeto original.

Me deparei com este interessante artigo do UncleBob The Little Mocker . Ele explica toda a terminologia de uma forma muito fácil de entender, por isso é útil para iniciantes. O artigo de Martin Fowlers é uma leitura difícil especialmente para iniciantes como eu.


O esboço é objeto falso simples. Apenas garante que o teste seja executado sem problemas.
Mock é stub mais inteligente. Você verifica que seu teste passa por ele.


O seguinte é o meu entendimento ...

  • Se você criar objetos de teste localmente e alimentar seu serviço local com isso, estará usando o objeto simulado. Isso dará um teste para o método implementado em seu serviço local. é usado para verificar comportamentos

  • Quando você obtém os dados de teste do provedor de serviço real, embora esteja usando uma versão de teste da interface e obtenha uma versão de teste do objeto, você está trabalhando com stubs. O stub pode ter lógica para aceitar determinada entrada e fornecer a saída correspondente para ajudá-lo a executar verificação de estado ...


Para ser muito claro e prático:

Stub: Uma classe ou objeto que implementa os métodos da classe / objeto a ser falsificado e retorna sempre o que você deseja.

Exemplo em JavaScript:

var Stub = {
   method_a: function(param_a, param_b){
      return 'This is an static result';
   }
}

Mock: O mesmo do stub, mas acrescenta alguma lógica que "verifica" quando um método é chamado, então você pode ter certeza de que alguma implementação está chamando esse método.

Como @mLevan diz, imagine como um exemplo que você está testando uma classe de registro de usuário. Depois de chamar Save, ele deve chamar SendConfirmationEmail.

Um código muito estúpido Exemplo:

var Mock = {
   calls: {
      method_a: 0
   }

   method_a: function(param_a, param_b){
     this.method_a++; 
     console.log('Mock.method_a its been called!');
   }
}

Ponto de vista do teste de esboço e simulação:

  • Stub é uma implementação fictícia feita pelo usuário de maneira estática , ou seja, no Stub que está escrevendo o código de implementação. Portanto, ele não pode manipular a definição de serviço e condição dinâmica, normalmente isso é feito na estrutura JUnit sem usar estrutura de simulação.

  • Mock também é uma implementação fictícia, mas sua implementação é feita de maneira dinâmica , usando estruturas Mocking como Mockito. Assim, podemos manipular a definição de condição e serviço como uma maneira dinâmica, ou seja, os mocks podem ser criados dinamicamente a partir do código em tempo de execução. Então, usando mock podemos implementar Stubs dinamicamente.


Um falso é um termo genérico que pode ser usado para descrever um esboço ou um objeto simulado (manuscrito ou não), porque ambos se parecem com o objeto real.

Se um falso é um stub ou um mock depende de como ele é usado no teste atual. Se é usado para checar uma interação (contra), é um objeto simulado. Caso contrário, é um esboço.

Fakes garante que o teste seja executado sem problemas. Isso significa que o leitor do seu futuro teste entenderá qual será o comportamento do objeto falso, sem precisar ler seu código fonte (sem precisar depender de recursos externos).

O que o teste corre suavemente significa?
Por exemplo, no código abaixo:

 public void Analyze(string filename)
        {
            if(filename.Length<8)
            {
                try
                {
                    errorService.LogError("long file entered named:" + filename);
                }
                catch (Exception e)
                {
                    mailService.SendEMail("[email protected]", "ErrorOnWebService", "someerror");
                }
            }
        }

Você quer testar o método mailService.SendEMail () , para fazer isso você precisa simular uma Exceção no seu método de teste, então você só precisa criar uma classe errorService do Stub Fake para simular esse resultado, então o seu código de teste será capaz de testar método mailService.SendEMail (). Como você vê, você precisa simular um resultado que é de uma outra classe ErrorService de Dependência Externa.


Um stub é um objeto falso criado para fins de teste. Uma simulação é um esboço que registra se as chamadas esperadas ocorreram efetivamente.


Um sujeito de teste executa ações em resposta a determinados prompts (chamadas de função) ou outros estímulos. Aqui estão exemplos concretos de situações de teste.

Cenário - exame de estudante de EMT

Um estudante estudou para ser um técnico de medicina de emergência. Vá assistir Ian Gallagher em Shameless Season 6, Episode 10 se você não estiver familiarizado com esta situação de teste.

É muito caro encontrar pacientes com várias doenças para fins de teste. Em vez disso, usamos atores. Perguntamos ao sujeito do teste (Ian) "você chega ao local e o paciente está imobilizado e inconsciente, o que você faz primeiro?" Ian responde "Eu verifico se a cena é segura". E o instrutor de teste diz "a cena é segura".

O instrutor (e o ator) é capaz de injetar respostas arbitrárias às consultas do sujeito de teste.

Aqui, o instrutor (e ator) é um simulado. A formação médica usa essa terminologia (por exemplo, simulação de código simulado) da mesma forma que os cientistas da computação.

Cenário - registre-se para um site

Você está testando o Yahoo, um novo serviço de e-mail de que você ouviu falar. Para se inscrever, você deve fornecer seu aniversário e respostas para outras perguntas intrusivas.

O site requer que você tenha 21 anos ou mais. Assim, você insere o valor em 1º de janeiro de 1970. Ele atende aos requisitos e evita que você trabalhe no processo de implementar um fluxo de trabalho "lembrar-meu-aniversário-e-digitar".

Esta data é um esboço. Esse uso de palavras é específico para a ciência da computação.


Usando um modelo mental realmente me ajudou a entender isso, ao invés de todas as explicações e artigos, que não "afundaram".

Imagine que seu filho tenha uma placa de vidro na mesa e ele comece a brincar com ela. Agora, você está com medo de quebrar. Então, você dá a ele uma placa de plástico. Isso seria um Mock (mesmo comportamento, mesma interface, implementação "mais suave").

Agora, diga que você não tem o substituto de plástico, então você explica: "Se você continuar jogando com ele, ele vai quebrar!". Isso é um esboço , você forneceu um estado pré-definido com antecedência.

Um Dummy seria o garfo que ele nem usava ... e um Spy poderia ser algo como fornecer a mesma explicação que você já usou e que funcionou. Um Fake seria como mentir que um policial virá se ele continuar (não tenho certeza sobre a última parte :).



vamos ver Test Doubles:

  • Fake : Fakes são objetos que possuem implementações de trabalho, mas não são iguais aos da produção. Tais como : implementação na memória do Data Access Object ou Repository.
  • Stub : Stub é um objeto que armazena dados predefinidos e os utiliza para atender chamadas durante os testes. Tais como : um objeto que precisa pegar alguns dados do banco de dados para responder a uma chamada de método.

  • Mocks : Mocks são objetos que registram chamadas recebidas. Na asserção de teste, podemos verificar no Mocks que todas as ações esperadas foram realizadas. Tais como : uma funcionalidade que chama o serviço de envio de e-mail. para mais, basta verificar this .


Stub nos ajuda a executar o teste. Como? Fornece valores que ajudam a executar o teste. Esses valores não são reais e criamos esses valores apenas para executar o teste. Por exemplo, criamos um HashMap para nos fornecer valores que são semelhantes aos valores na tabela do banco de dados. Então, em vez de interagir diretamente com o banco de dados, interagimos com o Hashmap.

Mock é um objeto falso que executa o teste. onde nós colocamos afirmação.


Um Stub é um objeto que implementa uma interface de um componente, mas, em vez de retornar o que o componente retornaria quando chamado, o stub pode ser configurado para retornar um valor adequado ao teste. Usando stubs, um teste unitário pode testar se uma unidade pode manipular vários valores de retorno de seu colaborador. Usando um stub em vez de um colaborador real em um teste unitário poderia ser expresso assim:

teste de unidade -> stub

teste de unidade -> unidade -> stub

teste unitário confirma os resultados e o estado da unidade

Primeiro, o teste unitário cria o stub e configura seus valores de retorno. Em seguida, o teste de unidade cria a unidade e define o stub nela. Agora, o teste de unidade chama a unidade que, por sua vez, chama o stub. Finalmente, o teste unitário faz afirmações sobre os resultados das chamadas do método na unidade.

Um Mock é como um esboço, só que ele também possui métodos que tornam possível determinar quais métodos foram chamados no Mock . Usando uma simulação, é possível testar se a unidade pode manipular corretamente vários valores de retorno e também se a unidade usa o colaborador corretamente. Por exemplo, você não pode ver pelo valor retornado de um objeto dao se os dados foram lidos do banco de dados usando uma instrução ou um PreparedStatement. Nem você pode ver se o método connection.close () foi chamado antes de retornar o valor. Isso é possível com mocks. Em outras palavras, as brincadeiras permitem testar uma interação completa das unidades com um colaborador. Não apenas os métodos do colaborador que retornam valores usados ​​pela unidade. Usando um mock em um teste unitário poderia ser expresso assim:

teste de unidade -> mock

teste de unidade -> unidade -> simulação

teste unitário confirma o resultado e o estado da unidade

teste de unidade afirma sobre os métodos chamados no simulado

Mais detalhes >> Here





stub