Unidades
Acho que posso identificar exatamente onde o problema começou:
I figured, I'll need a method that finds all the non-numerical fields in a line.
Isso deve ser imediatamente seguido com a pergunta "Isso será uma unidade testável separada para gatherNonNumericColumns
ou parte do mesmo?"
Se a resposta for " sim, separado ", o seu curso de ação é simples: esse método precisa ser público em uma classe apropriada, para que possa ser testado como uma unidade. Sua mentalidade é algo como "Eu preciso testar um método e também preciso testar outro método"
Pelo que você diz, você percebeu que a resposta é " não, parte do mesmo ". Neste ponto, seu plano não deve mais ser escrever e testar completamente findNonNumericFields
então escreva gatherNonNumericColumns
. Em vez disso, deve ser simplesmente escrever gatherNonNumericColumns
. Por enquanto, findNonNumericFields
deve ser apenas uma parte provável do destino que você tem em mente quando estiver escolhendo seu próximo caso de teste vermelho e fazendo sua refatoração. Desta vez, sua mentalidade é "Preciso testar um método, e enquanto faço isso, devo ter em mente que minha implementação final provavelmente incluirá esse outro método".
Mantendo um ciclo curto
Fazer o acima deve não levar aos problemas que você descreve no seu penúltimo parágrafo:
Because if I start out by writing a test for a public method, there will be several minutes (or hours, or even days in very complex cases) before I get all the details in the private methods to work so that the test testing the public method passes.
Em nenhum momento esta técnica exige que você escreva um teste vermelho que só ficará verde quando você implementar a totalidade de findNonNumericFields
do zero. É muito mais provável que findNonNumericFields
comece como um código in-line no método público que você está testando, que será compilado ao longo de vários ciclos e, eventualmente, extraído durante uma refatoração.
Roteiro
Para fornecer um roteiro aproximado para esse exemplo específico, não sei os casos de teste exatos que você usou, mas diga que você estava escrevendo gatherNonNumericColumns
como seu método público. Então, provavelmente, os casos de teste seriam os mesmos que você escreveu para findNonNumericFields
, cada um usando uma tabela com apenas uma linha. Quando esse cenário de uma linha foi totalmente implementado e você quis escrever um teste para forçá-lo a extrair o método, você escreveria um caso de duas linhas que exigiria que você adicionasse sua iteração.