["python","unit-testing","mocking","patch"]
Mocking a global variable

I've been trying to implement some unit tests for a module. An example module named alphabet.py is as follows: import database def length_letters(): return len(letters) def contains_letter(letter): return letter in letters letters = database.get('letters') # returns a list of letters I'd like to mock the response from a database with some values of my choice, but the code below doesn't seem to work. 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')) I have seen many examples in which 'patch' is applied to methods and classes, but not to variables. I prefer not to patch the method database.get because I may use it again with different parameters later on, so I would need a different response. What am I doing wrong here?
Try this: import unittests import alphabet from unittest import mock class TestAlphabet(unittest.TestCase): def setUp(self): self.mock_letters = mock.patch.object( alphabet, 'letters', return_value=['a', 'b', 'c'] ) def test_length_letters(self): with self.mock_letters: self.assertEqual(3, alphabet.length_letters()) def test_contains_letter(self): with self.mock_letters: self.assertTrue(alphabet.contains_letter('a')) You need to apply the mock while the individual tests are actually running, not just in setUp(). We can create the mock in setUp(), and apply it later with a with ... Context Manager.