Supponendo che tu voglia costruire test automatici per la seguente (molto semplice, se dispari) classe.
// Calculates the distance between neighboring values in a vector
// and provides functions to return the distance from one index to the following
// or to find the first occurrence of a specified distance
class NeighborDistanceFinder
{
public:
NeighborDistanceFinder(std::vector<int> inputVector)
: m_neighborVector(inputVector) { };
int getDistanceToNextIndex(int index) const
{
if (index >= 0 && index < m_neighborVector.size() - 1)
return (calculateDistance(index, index + 1);
throw "Provided index is invalid";
}
int getIndexOfFirstOccurenceOfDistance(int distance) const
{
for (int index = 0; index < m_neighborVector.size() - 1; i++)
{
if (calculateDistance(index, index + 1) == distance)
return index;
}
throw "Distance not found";
}
private:
std::vector<int> m_neighborVector;
int calculateDistance(int index, int otherIndex) const
{
const int lastIndex = m_neighborVector.size() - 1;
if (index < 0 || otherIndex < 0 || index > lastIndex || otherIndex > lastIndex)
throw "Index of of bounds"; //This should never happen
return m_neighborVector.at(firstIndex) - m_neighborVector.at(secondIndex);
}
}
In una classe così semplice il controllo dei limiti per calculateDistance()
è probabilmente eccessivo, ma immagina che la condizione per controllare sia più complessa di un semplice controllo dei limiti e più funzioni che chiamano calculateDistance()
, funzioni funzioni con m_neighborVector
e presto sembra sempre più attraente ...
In ogni caso, con questo capolavoro a portata di mano ci rendiamo conto che non abbiamo fatto il TDD e non abbiamo nessun test unitario. Beh, niente paura, sono abbastanza semplici da aggiungere (... qualche ora dopo ...). Fatto.
Ma c'è una lacuna nella nostra copertura del codice: non possiamo raggiungere throw "Index of of bounds";
(a meno che non abbia commesso un errore nello scrivere questo esempio ...). Bene, naturalmente, prendiamo i casi fuori limite nelle due funzioni pubbliche che lo invocano, e la funzione è privata, quindi non possiamo invocarla direttamente (poiché non abbiamo una riflessione in C ++). Lo so, l'analisi statica del codice dovrebbe essere in grado di dirci che questo è essenzialmente un codice morto, ma ancora: Immagina che la condizione sia più complessa.
Quindi cosa si dovrebbe fare riguardo a questa funzione privata molto difensiva a questo punto?
- Il divario va bene - non hai bisogno (e non otterrai mai) copertura al 100% - vai avanti.
- Questa è una programmazione difensiva eccessiva in una funzione privata - elimina il controllo, FFS.
- Devi coprire questo - spostare la funzione in protetto o rendere il tuo test una classe di amici, ecc.
- E ora qualcosa di completamente diverso?