Funzioni di test dell'unità che chiamano altre funzioni testate [duplicate]

1

Ho tre funzioni:

  • ValidateUsername() , che determina se una stringa è un nome utente valido secondo alcune regole
  • SetUsername() che imposta una stringa come Username dell'utente se supera la convalida
  • AddNewUser() , che crea un nuovo utente e, tra le altre cose, imposta una stringa come sua Username usando SetUsername()

Tutti e tre dovrebbero fallire se la stringa nome utente fornita non è corretta, tuttavia ValidateUsername() è dove si trovano le regole. Come posso testare questo? Il test della convalida solo in ValidateUsername() lascia la possibilità che qualcuno ometta erroneamente la convalida e imposta il nome utente direttamente in AddNewUser() . D'altra parte, la ripetizione di tutti i diversi casi di test di convalida per tutte le funzioni sembra controproducente. Qual è la migliore pratica?

    
posta io-quois 22.06.2015 - 19:24
fonte

3 risposte

3

Il test delle unità viene chiamato in questo modo perché stai pensando di testare le unità di lavoro, nel tuo caso ogni metodo è un'unità di lavoro e non l'intera integrazione tra loro.

Supponiamo che il tuo requisito aziendale per il metodo ValidateUsername () sia quello di convalidare il nome utente in base a determinati requisiti. Il tuo test unitario in questo caso dovrebbe verificare che la convalida sia corretta e che le regole siano implementate correttamente.

Ora ti sembra di avere altri metodi, uno dei requisiti aziendali è chiamare il metodo di convalida: fai proprio questo. Assicurarsi che il ValidateUsername sia stato effettivamente chiamato. Non ti importa se è stato eseguito correttamente o meno - quella parte deve essere testata dal test precedente per l'unità ValidateUsername.

    
risposta data 22.06.2015 - 22:29
fonte
4

È possibile verificare che la funzione di convalida sia stata chiamata testando le altre due funzioni con un nome non valido e un nome valido. Oppure puoi separare la logica in UsernameValidator e UserService e iniettare il validatore nel servizio utente. Quindi testerai il servizio utente simulando il validatore.

    
risposta data 22.06.2015 - 19:33
fonte
1

Se sto interpretando correttamente la tua domanda, AddNewUser() chiama SetUsername() e SetUsername() chiama ValidateUsername() . Vengono in mente due opzioni:

1) Mantieni la struttura esistente e scrivi test unitari per "una cosa" di cui è responsabile ogni funzione, assumendo il "percorso felice" per le sue dipendenze. Quindi i test ValidateUsername() controllerebbero nomi utente validi e non validi, il test SetUsername() passerebbe in un nome utente valido e si assicurerà che quel nome utente finisca nel posto giusto, e il test AddNewUser() passi in dati di costruzione utente validi e assicurati che un utente sia stato aggiunto utilizzando tali dati.

2) Cambia la struttura in qualcosa di "più piatto" in modo che le funzioni non dipendano più l'una dall'altra. Pertanto potresti avere una funzione AttemptToAddUser() che chiama ValidateUsername() , quindi SetUsername() , poi AddNewUser() tutti allo stesso livello dello stack di chiamate.

La risposta ottimale dipende in larga misura dal codice esatto, ma mi aspetterei che sia la prima o la seconda tra # 1 e # 2. Potrebbe essere perfettamente sensato tirare ValidateUsername() fino allo stesso livello di AddNewUser() , ma ho difficoltà a immaginare una funzione SetUsername() di qualsiasi utilizzo al di fuori della funzione AddNewUser() (assumendo che non sia un metodo su un Oggetto utente o qualcosa del genere.

Ovviamente, indipendentemente da come funzionano i test unitari, probabilmente vorrai ancora un piccolo numero di test di integrazione che controllino tutte queste funzioni insieme.

    
risposta data 22.06.2015 - 23:22
fonte

Leggi altre domande sui tag