até onde eu entendo, a maioria das pessoas parece concordar que os métodos privados não devem ser testados diretamente, mas através de métodos públicos. Eu entendo o argumento deles, mas tenho alguns problemas com isso quando tento seguir as "Três Leis do TDD" e usar o ciclo "Vermelho - verde - refatorador". Eu acho que é melhor explicado por um exemplo:
No momento, preciso de um programa que possa ler um arquivo (contendo dados separados por tabulações) e filtrar todas as colunas que contêm dados não numéricos. Acho que provavelmente já existem algumas ferramentas simples disponíveis para fazer isso, mas decidi implementá-lo do zero, principalmente porque achei que poderia ser um projeto agradável e limpo para eu praticar um pouco com o TDD.
Então, primeiro, "coloco o chapéu vermelho", ou seja, preciso de um teste que falhe. Imaginei, precisarei de um método que encontre todos os campos não numéricos em uma linha. Então, eu escrevo um teste simples, é claro que ele falha na compilação imediatamente, então começo a escrever a função em si e, depois de alguns ciclos para frente e para trás (vermelho / verde), tenho uma função de trabalho e um teste completo.
Em seguida, continuo com uma função "gatherNonNumericColumns" que lê o arquivo, uma linha de cada vez, e chama minha função "findNonNumericFields" em cada linha para reunir todas as colunas que eventualmente devem ser removidas. Um par de ciclos vermelho-verde, e eu terminei, tendo novamente uma função de trabalho e um teste completo.
Agora, acho que devo refatorar. Como meu método "findNonNumericFields" foi projetado apenas porque achei que seria necessário ao implementar "gatherNonNumericColumns", parece-me que seria razoável permitir que "findNonNumericFields" se tornasse privado. No entanto, isso interromperia meus primeiros testes, pois eles não teriam mais acesso ao método que estavam testando.
Então, acabo com métodos particulares e um conjunto de testes que o testam. Como muitas pessoas aconselham que métodos privados não devem ser testados, parece que eu me pintei de canto aqui. Mas onde exatamente eu falhei?
Acho que poderia ter começado em um nível mais alto, escrevendo um teste que testa o que acabará se tornando meu método público (ou seja, findAndFilterOutAllNonNumericalColumns), mas isso parece um pouco contrário ao ponto inteiro do TDD (pelo menos de acordo com o tio Bob) : Que você deve alternar constantemente entre escrever testes e código de produção e que, a qualquer momento, todos os seus testes funcionaram no último minuto ou mais. Porque se eu começar escrevendo um teste para um método público, haverá vários minutos (ou horas ou mesmo dias em casos muito complexos) antes que eu obtenha todos os detalhes nos métodos privados para que o teste teste o público método passa.
Então o que fazer? O TDD (com o rápido ciclo de refator vermelho-verde) simplesmente não é compatível com métodos particulares? Ou há uma falha no meu design?
private
se fizesse sentido.