Teste de unidade e simulação
Parece haver muitas dúvidas sobre "quando zombar". Mas eu não obtive uma resposta para minha pergunta até agora. Pode ser, não conheço uma solicitação de pesquisa específica que me indicasse a resposta.
Imagine que temos uma classe (MyClass). Imagine que essa classe tenha métodos que podem retornar tanto std :: string quanto um objeto de classe wrapper (MyStringWrapper definido em outra biblioteca). MyStringWrapper não é exatamente agregador (podemos considerar o uso de struct aqui, mas vamos preferir uma classe para este exemplo em particular), já que seu setter tem um if e várias operações de cópia. Agora, existe uma 3ª classe (UserClass) que usa as classes MyClass e MyStringWrapper.
Como um bom desenvolvedor de SW, gostaria de fazer um teste de unidade em minha UserClass (como muitos se referem a "cheirar um código"). Para o teste de unidade, eu usaria gtests e gmock para criar um mock de MyClass (vamos chamá-lo de MyClassMock). No entanto, lembro que em algum lugar foi dito "você tem que simular tudo, o que está definido em outra biblioteca / biblioteca de terceiros". Ambos std :: string e MyStringWrapper são definidos em bibliotecas de terceiros.
Agora a pergunta. Portanto, devo, neste caso, criar simulações para std :: string e MyStringWrapper?
Você pode imaginar o uso do objeto std :: string / MyStringWrapper retornado como
if(myreturnedstdstring.empty())
return 1;
if(mywrapperobject.failed())
return 100;
Fui questionado em comentários aqui Há um ponto para testes de unidade que esboçam e simulam tudo que é público?
crie outro tópico.
Respostas
Tudo em std :: faz parte da linguagem e não deve ser ridicularizado. Seu invólucro de string, se não for parte da "unidade" em teste, pode ser simulado, mas IMHO e experimentar um invólucro como esse geralmente é tão leve que o simulado essencialmente reproduziria o código. Nesse caso, eu não zombaria disso. No entanto, se o invólucro puder ser alterado no futuro, você deve simulá-lo se quiser um teste de unidade estável. Por outro lado, ter uma falha no teste quando uma alteração incompatível é feita no invólucro seria bom, mas mais difícil de rastrear, pois o erro estará em alguma outra unidade.
Lembro que em algum lugar foi dito "você tem que zombar de tudo, o que está definido em outra biblioteca / biblioteca de terceiros".
Esse pode ter sido o conselho uma vez, mas não é o conselho comumente dado hoje.
O conselho atual é usar a simulação com moderação para ajudar a esses objetivos do teste de unidade:
- Os testes podem ser executados rapidamente, em paralelo ou em qualquer ordem e a qualquer momento. Isso implica que os componentes que interagem com armazenamento persistente (bancos de dados, sistemas de arquivos), conexões lentas (rede) ou condições ambientais que você não pode controlar facilmente (por exemplo, tempo) são candidatos para simulação.
- Todos os caminhos através do código em teste podem ser exercitados. Se uma determinada resposta (erro) de uma dependência não pode ser facilmente disparada com o código real, então isso pode ser um motivo para simular essa dependência.
Tipos de dados simples, como strings, seu MyStringWrapper ou mesmo contêineres não se encaixam nesses pontos, então não há razão para zombar deles.