Python Mock - Dormire diversi aperti
-
27-10-2019 - |
Domanda
Dopo aver letto questo: Come faccio a deridere un aperto usato in una dichiarazione con WITH (usando il framework finto in Python)?
Sono in grado di deridere la funzione aperta in Python usando:
with patch(open_name, create=True) as mock_open:
mock_open.return_value = MagicMock(spec=file)
m_file = mock_open.return_value.__enter__.return_value
m_file.read.return_value = 'text1'
diffman = Diffman()
diffman.diff(path1, path2)
Funziona bene quando il mio metodo testato ha utilizzato un'istruzione aperta. Ecco il mio metodo testato:
def diff(self, a, b):
with open(a, 'r') as old:
with open(b, 'r') as new:
oldtext = old.read()
newtext = new.read()
I valori di OldText e NewText sono gli stessi ('text1' qui).
Vorrei avere "text1" per il vecchio e "text2" per il nuovo.
Come posso fare questo ?
Soluzione
Ecco un modo rapido per ottenere ciò che vuoi. Truffa un po 'perché i due oggetti file nel metodo in test sono lo stesso oggetto e stiamo solo cambiando il valore di ritorno della chiamata di lettura dopo ogni lettura. È possibile utilizzare la stessa tecnica in più livelli se si desidera che gli oggetti del file siano diversi, ma sarà abbastanza disordinato e potrebbe mascherare inutilmente l'intento del test.
Sostituisci questa riga:
m_file.read.return_value = 'text1'
insieme a:
reads = ['text1', 'text2'] m_file.read.side_effect = lambda: reads.pop(0)
Altri suggerimenti
Forse una buona soluzione possibile è solo scrivere il codice in un modo che si presta meglio a testarlo facilmente. Nel caso di "diff", sembra abbastanza facile (non avere molto altro contesto, è vero) avere differen come argomenti di oggetti di file già aperti. Questa è probabilmente una modifica abbastanza piccola da apportare nel codice e rende i test molto semplici, poiché è possibile fornire facilmente oggetti di file finti a diff () quando lo si testano, invece di provare a saltare attraverso i cerchi deridendo due istanze dello stesso Funzione incorporata come un gestore del contesto chiamato all'interno ... stesso ... o qualcosa del genere ;-)
import StringIO
diff(a, b):
oldtext = a.read()
newtext = b.read()
def test_diff():
a = StringIO.StringIO('text1')
b = StringIO.StringIO('text2')
res = diff(a, b)
<some assertion here>
Funzionerebbe per il tuo caso?