Ho molta familiarità con i framework xUnit e cerco di implementare i test unitari su ogni progetto che inizio. Da qualche parte lungo la strada, mi rendo conto che sto scrivendo gli stessi test più e più volte, e poi mi imbatto in un metodo davvero difficile da testare o un test che coinvolge risorse remote, e poi mi arrendo per un po '. Finisco per tornare con entusiasmo ogni volta che posso testare cose semplici, ma non appena mi imbatto in cose più difficili da testare, corro per le colline con la coda tra le gambe.
Facciamo alcuni esempi.
-
Lungo flusso di cose da fare in un metodo. (Come faccio a testarlo? Mi limito ad assicurarmi che il codice venga chiamato eliminando le cose? Come dovrei riscrivere il codice per facilitare i test?)
public void doSomething() { Object1 value1 = doSomething1(this.getName()); if (value1.isError()) { sendError(new Object1Error(value1.getError().getMessage())); return; } Object2 value2 = doSomething2(value1, this.getName()); if (value2.isError()) { sendError(new Object2Error(value2.getError().getMessage())); return; } /* ad infinitum... */ }
-
Metodi e costruttori sovraccaricati.
public String toJSON() { return toJSON(true); } public String toJSON(boolean prettyPrint) { /* do work */ return result; } /* test */ @Test public void testToJSON() { ... }; @Test public void testToJSONBoolean() { /* redundant similar test code... */ }
-
Risorse remote. Come faccio a testare che la mia API di caricamento funzioni (es. Metodo di richiesta giusta, host, tipo di contenuto della richiesta, payload, ecc.) Senza fare effettivamente un upload? Questi caricamenti vengono inviati a server al di fuori del mio controllo.
public void doUpload() throws IOException { HttpClient client = new HttpClient(); PutMethod putMethod = new PutMethod(...); putMethod.setRequestHeader(...); putMethod.setRequestEntity(new FileInputStreamRequestEntity(...)); /* etc. */ final int responseCode = client.executeMethod(putMethod); }
-
Verifica interazioni server con i clienti.
/* before we even get here, other interactions need to take place */ public void updateClientProfile(UserProfile profile) { // 1. validate the input // 2. update the user in the db // 3. generate an email in HTML // 4. send the email // 5. serve out a view }
I test a prima vista sembrano facili, finché non arrivo a questo tipo di situazioni. Come mantenere la mia motivazione per i test e scrivere il mio codice per essere più testabile?
Sembra che più cose che un metodo deve fare, i test unitari esponenzialmente più difficili e frustranti da scrivere. Devo testare semplicemente che il codice sta chiamando i giusti servizi e metodi? Scrivo test unitari semplicemente per provare a me stesso che il mio codice chiama i metodi che ho detto di chiamare o per determinare se la logica è giusta? Aiuto!