Я пытался реализовать некоторые модульные тесты для модуля. Пример модуль с именем alphabet.py выглядит следующим образом:Смещение глобальной переменной
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
Я хотел бы, чтобы дразнить ответ из базы данных с некоторыми значениями моего выбора, но ниже код не похож на работу.
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'))
Я видел много примеров, в которых «патч» применяется к методам и классам, но не к переменным. Я предпочитаю не исправлять метод database.get, потому что я могу использовать его снова с разными параметрами позже, поэтому мне нужен другой ответ.
Что я здесь делаю неправильно?
Несчастливым следствием этого подхода является то, что любой другой тест, который использует эту переменную уровня модуля, потерпит неудачу, если вы не сохраните старое значение и не вернете его. Подделка позаботится об этом для вас. –
Вы можете установить значение 'alphabet.letters' обратно на то, что было в функции' tearDown'. – tomas
Кроме того, поскольку 'setUp' привязан ко всему тестовому классу, вы можете использовать это значение только для букв. Ответ Уилла ниже позволяет вам делать несколько макетов для разных тестовых случаев, и они очищаются в конце, поэтому нет риска случайного загрязнения. – raindrift