Ho cercato di implementare alcuni test unitari per un modulo. Un modulo di esempio di nome alphabet.py è la seguente:Mocking una variabile globale
import database
def length_letters():
return len(letters)
def contains_letter(letter):
return True if letter in letters else False
letters = database.get('letters') # returns a list of letters
mi piacerebbe prendere in giro la risposta da un database con alcuni valori della mia scelta, ma il codice qui sotto non sembra funzionare.
import unittests
import alphabet
from unittest.mock import patch
class TestAlphabet(unittest.TestCase):
@patch('alphabet.letters')
def setUp(self, mock_letters):
mock_letters.return_value = ['a', 'b', 'c']
def test_length_letters(self):
self.assertEqual(3, alphabet.length_letters())
def test_contains_letter(self):
self.assertTrue(alphabet.contains_letter('a'))
Ho visto molti esempi in cui 'patch' è applicata a metodi e classi, ma non a variabili. Preferisco non applicare la patch al metodo database.get perché potrei utilizzarlo di nuovo con parametri diversi in seguito, quindi avrei bisogno di una risposta diversa.
Cosa sto facendo di sbagliato qui?
Una sfortunata conseguenza di questo approccio è che qualsiasi altro test che utilizza questa variabile di livello modulo avrà esito negativo a meno che non si memorizzi il vecchio valore e lo si reinserisca. Mocking si prende cura di questo per te. –
È possibile impostare il valore di 'alphabet.letters' su ciò che era nella funzione' tearDown'. – tomas
Inoltre, poiché 'setUp' ha un ambito per l'intera classe di test, puoi usare solo questo valore per' letters'. La risposta di Will qui sotto ti consente di fare più simulazioni per diversi casi di test, e si ripuliscono alla fine, quindi non c'è rischio di inquinamento da test accidentali. – raindrift