In risposta a il codice è testabile codice migliore? I showed in che modo il codice dipendente dal tempo può essere verificabile utilizzando i mock anziché modificare l'implementazione:
def time_of_day():
return datetime.datetime.utcnow().strftime('%H:%M:%S')
Codice test:
@unittest.patch('datetime.datetime.utcnow')
def test_handle_leap_second(self, utcnow_mock):
utcnow_mock.return_value = datetime.datetime(
year=2015, month=6, day=30, hour=23, minute=59, second=60)
actual = time_of_day()
expected = '23:59:60'
self.assertEquals(actual, expected)
Il problema qui (a parte Python che non gestisce i secondi bisestili ) è che il codice di test presuppone che utcnow
restituirà un oggetto datetime.datetime
in tutte le situazioni. Potrebbe essere vero in questo momento per questa funzione specifica con l'interprete corrente ecc., ma se il tipo di ritorno cambia per qualsiasi ragione il test passerà quando probabilmente dovrebbe fallire. Quindi per una robusta suite di test sarebbe meglio garantire che il valore di ritorno fittizio abbia la stessa classe del valore di ritorno della funzione originale. Questo è ovviamente possibile solo nelle lingue in cui il tipo di ritorno è applicato dal compilatore o dall'interprete. Puoi aggirare questo problema modificando un valore di ritorno della funzione originale piuttosto che crearne uno tuo:
utcnow_mock.return_value = datetime.datetime.utcnow().replace(
year=2015, month=6, day=30, hour=23, minute=59, second=60)
Ora stiamo operando con un diverso insieme di ipotesi:
-
replace
modifica l'oggetto restituito dautcnow
invece di restituire qualche oggetto diverso . Questo non sarà un problema se le proprietà dell'oggetto rilevanti sono scrivibili. -
utcnow
restituisce sempre oggetti con la stessa classe.
Quale metodo è più probabile che generi una suite di test robusta? Tieni presente che, a differenza di questo esempio, la creazione e la modifica di un oggetto potrebbe essere più semplice della creazione con le proprietà corrette da zero.