Reputation: 2851
test.py:
@pytest.mark.django_db
def test_b_called(mocker):
b = mocker.patch('app.service.b')
service.a('b')
assert b.called
service.py:
def a(type):
_actions[type]()
def b():
pass
_actions = { 'b': b }
My test will fail as my patch does not work as I expected. What am I doing wrong here? This definitely works if a
calls b
directly and not using that dictionary. I have tested for this. I know you can mock a dictionary with patch.dict
but then how would I test that b
was called?
Upvotes: 3
Views: 2332
Reputation: 2851
I was trying to mock the dictionary action with a function that does nothing. Instead, I should have mocked it to a MagicMock
function which is what a patch does as well.
patch.dict(
'app.service._actions',
{'b': MagicMock} # MagicMock is imported from unittest.mock
)
Upvotes: 0
Reputation: 1721
So I would argue that these are two separate unit tests, one for function a and one for the dictionary _actions.
_actions is not just a simple dictionary but in a sense a dynamic function call. So if you are truly testing just function a then you need to patch the _actions object and just test the functionality in the scope of the function.
_actions is out of the testing scope and should be tested individually like any other method.
from unittest import TestCase
from unittest.mock import patch
from stack_overflow import a,b,c, _actions
class TestStack(TestCase):
def setUp(self):
super().setUp()
def tearDown(self):
super().tearDown()
@patch.dict('stack_overflow._actions',{'b':b})
def test_a(self):
self.assertEqual(5,a('b'))
def test__actions_def_b(self):
self.assertEqual(_actions['b'],b)
def test__actions_def_c(self):
self.assertEqual(_actions['c'],c)
def a(type):
current_actions = _actions
return _actions[type]()
def b():
return 5
def c():
return 7
_actions = { 'b': b, 'c': c}
Upvotes: 1