Sto scrivendo alcune app Objective-C (per OS X / iOS) e attualmente sto implementando un servizio per condividerle. Il servizio è destinato ad essere abbastanza autonomo.
Per la funzionalità attuale immagino che ci sarà un solo metodo che i client chiameranno per fare una serie di passaggi abbastanza complicata sia usando metodi privati sulla classe, sia passando dati attraverso una serie di "classi di manipolazione dei dati" a arriva a un risultato finale.
L'essenza del codice è di recuperare un registro delle modifiche, memorizzato in un archivio dati interno al servizio, che si è verificato da un particolare momento, semplifica il registro per includere solo l'ultima modifica applicabile per ciascun oggetto, allegare il serializzato valori per gli oggetti interessati e restituire tutto al client.
La mia domanda allora è, come posso testare questo metodo di ingresso? Ovviamente, ogni classe dovrebbe avere test unitari accurati per assicurare che la loro funzionalità funzioni come previsto, ma il punto di ingresso sembra più difficile da "disconnettere" dal resto del mondo. Preferirei non inviare in ognuna di queste classi interne lo stile IoC, perché sono piccole e sono fatte solo classi per soddisfare il principio della responsabilità unica.
Vedo un paio di possibilità:
- Creare un'intestazione di interfaccia "privata" per i test con metodi che chiamano le classi interne e testa ciascuno di questi metodi separatamente. Quindi, per testare il punto di ingresso, crea un mock parziale della classe di servizio con questi metodi privati mocked e prova solo che i metodi siano chiamati con gli argomenti giusti.
- Scrivi una serie di test più grassi per il punto di ingresso senza prendere in giro nulla, testando l'intera funzionalità in un colpo solo. Questo mi sembra più simile a "test di integrazione" e sembra fragile, ma soddisfa il principio del "solo test tramite l'interfaccia pubblica".
- Scrivi uno stabilimento che restituisce questi servizi interni e prendi quello nell'inizializzatore, quindi scrivi uno stabilimento che restituisca versioni fittizie di essi da utilizzare nei test. Questo ha il rovescio della medaglia nel rendere fastidiosa la costruzione del servizio e fa filtrare i dettagli interni al client.
- Scrivi un inizializzatore "privato" che utilizzi questi servizi come parametri aggiuntivi, utilizzalo per fornire servizi di simulazione e reinserire l'inizializzatore pubblico su questo. Ciò assicurerebbe che il codice client veda ancora l'inizializzatore facile / carino e che non vi siano perdite di internals.
Sono sicuro che ci sono altri modi per risolvere questo problema a cui non avevo ancora pensato, ma la mia domanda è: qual è l'approccio più appropriato in base alle migliori pratiche di test unitario? Soprattutto considerando che preferirei scrivere questo test-first, nel senso che preferibilmente dovrei creare questi servizi solo perché il codice indica una necessità per loro.