Parece um problema de galinha e ovo.
Você pode gravar uma função de gravação em algum armazenamento de dados, mas nunca sabe que a salvou corretamente sem uma função de leitura testada.
Você pode fazer com que uma função de leitura seja lida em um armazenamento de dados, mas como você coloca coisas nesse armazenamento de dados para ler, sem uma função de gravação testada?
EDITAR:
Estou me conectando e fazendo transações com um banco de dados SQL para salvar e carregar objetos para uso. Não faz sentido testar as funções de acesso que o banco de dados fornece, mas envolvo essas funções para serializar / desserializar os objetos. Quero ter certeza de que estou escrevendo e lendo as coisas certas de e para o banco de dados corretamente.
Não é como adicionar / excluir, como o @snowman menciona. Quero saber que o conteúdo que escrevi está correto, mas isso requer uma função de leitura bem testada. Quando eu leio, quero ter certeza de que minha leitura criou corretamente um objeto igual ao que foi escrito; mas isso requer uma função de gravação bem testada.
Respostas:
Comece com a função de leitura.
Na configuração de teste : crie o banco de dados e adicione dados de teste. via scripts de migração ou de um backup. Como este não é o seu código, ele não requer um teste no TDD
No teste : instanciar seu repositório, aponte para o seu banco de dados de teste e chame o método Read. Verifique se os dados de teste foram retornados.
Agora você tem uma função de leitura totalmente testada, pode passar para a função Write, que pode usar a leitura existente para verificar seus próprios resultados
fonte
Costumo fazer uma gravação seguida de uma leitura. por exemplo (pseudocódigo)
Adicionado mais tarde
Além de essa solução ser "prgamatic" e "good enough", pode-se argumentar que as outras soluções testam a coisa errada . Testar se as strings ou instruções SQL correspondem não é uma péssima idéia, eu mesmo a fiz, mas está testando um efeito colateral e é frágil. E se você alterar a capitalização, adicionar um campo ou atualizar um número de versão nos seus dados? E se o seu driver SQL alternar a ordem das chamadas de eficiência, ou o serializador XML atualizado adicionar um espaço extra ou alterar uma versão do esquema?
Agora, se você deve aderir estritamente a algumas especificações oficiais, concordo que a verificação dos detalhes é apropriada.
fonte
Não. Não faça E / S de teste de unidade. É uma perda de tempo.
Lógica de teste de unidade. Se houver muita lógica que você deseja testar no código de E / S, refate seu código para separar a lógica de como você faz E / S e o que você faz dos negócios reais de fazer E / S (o que é quase impossível de testar).
Para elaborar um pouco, se você quiser testar um servidor HTTP, faça-o através de dois tipos de testes: testes de integração e testes de unidade. Os testes de unidade não devem interagir com a E / S. Isso é lento e apresenta muitas condições de erro que nada têm a ver com a correção do seu código. Os testes de unidade não devem estar sujeitos ao estado da sua rede!
Seu código deve separar:
Os dois primeiros envolvem lógica e decisões e precisam de testes de unidade. O último não envolve tomar muitas decisões, se houver, e pode ser testado maravilhosamente usando o teste de integração.
Na verdade, esse é apenas um bom design, na verdade, mas uma das razões é que facilita o teste.
aqui estão alguns exemplos:
fonte
Eu não sei se isso é uma prática padrão ou não, mas funciona bem para mim.
Nas minhas implementações de método de gravação e leitura que não são do banco de dados, eu uso meus próprios métodos
toString()
e tipos específicosfromString()
como detalhes de implementação.Estes podem ser facilmente testados isoladamente:
Para os métodos reais de leitura e gravação, eu tenho um teste de integração que lê e grava fisicamente em um teste
A propósito: Há algo errado em ter um teste que lê / escreve juntos?
fonte
Os dados conhecidos devem ser formatados de maneira conhecida. A maneira mais fácil de implementar isso é usar uma string constante e comparar o resultado, como @ k3b descrito.
Você não está limitado a constantes. Pode haver várias propriedades dos dados gravados que você pode extrair usando um tipo diferente de analisador, como expressões regulares, ou mesmo análises ad hoc que procuram recursos dos dados.
Quanto à leitura ou gravação dos dados, pode ser útil ter um sistema de arquivos na memória que permita executar seus testes sem a possibilidade de interferência de outras partes do sistema. Se você não tiver acesso a um bom sistema de arquivos na memória, use uma árvore de diretórios temporária.
fonte
Use injeção de dependência e zombaria.
Você não deseja testar seu driver SQL e não deseja testar se o banco de dados SQL está online e configurado corretamente. Isso faria parte de um teste de integração ou sistema. Você deseja testar se o seu código envia as instruções SQL que ele deve enviar e se ele interpreta as respostas da maneira que deveria.
Portanto, quando você tem um método / classe que deve fazer algo com um banco de dados, não obtenha essa conexão com o banco de dados por si só. Altere-o para que o objeto que representa a conexão com o banco de dados seja passado para ele.
No seu código de produção, passe o objeto de banco de dados real.
Nos testes de unidade, passe um objeto simulado que se comporta como um banco de dados real e não entra em contato com um servidor de banco de dados. Basta verificar se ele recebe as instruções SQL que deveria receber e, em seguida, responde com respostas codificadas.
Dessa forma, você pode testar a camada de abstração do banco de dados sem precisar de um banco de dados real.
fonte
Se você estiver usando um mapeador relacional de objetos, normalmente há uma biblioteca associada que pode ser usada para testar se seus mapeamentos funcionam corretamente criando um agregado, persistindo e recarregando-o de uma nova sessão, seguido pela verificação do estado em relação a o objeto original.
O NHibernate oferece teste de especificação de persistência . Ele pode ser configurado para funcionar com um armazenamento na memória para testes rápidos de unidade.
Se você seguir a versão mais simples dos padrões Repositório e Unidade de Trabalho e testar todos os seus mapeamentos, poderá contar com as coisas praticamente funcionando.
fonte