Pergunta

Eu uso NMock2, e eu já elaborou as seguintes classes NMock para representar alguns conceitos-quadro simulados comuns:

  • Expect:. Isto especifica o que é um método zombou deve retornar e diz que a chamada deve ocorrer ou o teste falha (quando acompanhadas por uma chamada para VerifyAllExpectationsHaveBeenMet())

  • Stub:. Isto especifica o que é um método zombou deve retornar, mas não pode causar um teste para falhar

Assim que devo fazer quando?

Foi útil?

Solução

Um monte de quadros zombando estão trazendo os conceitos de simulações e topos mais perto e mais perto junto a tal ponto que eles podem ser considerados funcionalmente quase o mesmo. De uma perspectiva conceitual no entanto, eu costumo tentar seguir esta convenção:

  • Mock :. Só quando você está explicitamente tentando verificar o comportamento do objeto em teste (ou seja, o teste está dizendo que esse objeto deve chamar esse objeto)
  • Stub : Quando você está tentando testar algumas funcionalidades / comportamento, mas a fim de obter esse trabalho você precisa confiar em alguns objetos externos (ou seja, o teste está dizendo que esse objeto deve fazer algo , mas como um efeito colateral, pode chamar esse objeto)

Isto torna-se mais clara quando você se certificar de que cada um de seus testes de unidade única testar uma coisa. Claro, se você tentar testar tudo em um teste, em seguida, assim como você pode esperar tudo. Mas em apenas esperando as coisas que teste de unidade específica está verificando, seu código é muito mais clara, porque você pode ver de relance o que a finalidade do teste é.

Outra vantagem disso é que você vai ser um pouco mais isolado da mudança e obter melhores mensagens de erro quando uma mudança provoca uma ruptura. Em outras palavras, se você subtley mudar alguma parte de sua implementação, o seu mais provável conseguir apenas um teste caso de ruptura, que irá mostrar-lhe exatamente o que está quebrado, em vez de todo um conjunto de testes quebrando & apenas criar ruído.

Editar : Pode ser mais claro com base em um exemplo inventado, onde um objeto calculadora audita todas as adições a um banco de dados (em pseudo-código) ...

public void CalculateShouldAddTwoNumbersCorrectly() {
    var auditDB = //Get mock object of Audit DB
    //Stub out the audit functionality...
    var calculator = new Calculator(auditDB);
    int result = calculator.Add(1, 2);
    //assert that result is 3
}

public void CalculateShouldAuditAddsToTheDatabase() {
    var auditDB = //Get mock object of Audit DB
    //Expect the audit functionality...
    var calculator = new Calculator(auditDB);
    int result = calculator.Add(1, 2);
    //verify that the audit was performed.
}

Assim, no primeiro caso de teste que estamos testando a funcionalidade do método Add e não se importam se um evento de auditoria ocorre ou não, mas nós acontecer para saber que a calculadora não vai funcionar com fora uma referência auditDB assim nós apenas stub-lo para nos dar o mínimo de funcionalidade para obter o nosso caso de teste específico de trabalho. No segundo teste estamos testando especificamente que quando você faz um Add, o evento de auditoria acontece, então aqui nós usamos expectativas (aviso de que nós nem sequer importa o que o resultado é, uma vez que não é isso que estamos testando).

Sim, você pode combinar os dois casos em um, e fazer as expectativas e afirmar que o seu resultado é 3, mas então você está testando dois casos em um teste de unidade. Isto faria com que seus testes mais frágil (uma vez que há uma maior área de superfície das coisas que poderiam mudar para quebrar o teste) e menos claro (desde quando o teste incorporada falhar não é imediatamente óbvio que o problema é .. é a adição não está funcionando, ou se a auditoria não está funcionando?)

Outras dicas

"Espere ações, consultas stub". Se a chamada deve alterar o estado do mundo fora do objeto em teste, em seguida, torná-lo uma expectativa - você se importa como ele é chamado. Se é apenas uma consulta, você pode chamá-lo uma vez ou seis vezes sem alterar o estado do sistema, em seguida, stub a chamada.

Mais uma coisa, aviso de que a distinção é entre canhotos e expectativas, ou seja chamadas individuais, objetos não necessariamente inteiros.

Bem ... IMHO ele não pode ser mais simples: se o seu teste consiste em garantir o seu Apresentador chamará Save, que uma Espere. Se o teste consiste em garantir o seu Presenter irá lidar com exceção graciosamente se Salvar joga-se, faça um topo.

Para mais detalhes, consulte a este podcast por Hanselman e Osherove (autor de a arte de testes de unidade)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top