如何模拟从字典调用的函数?
How can I mock a function called from a dictionary?
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 }
我的测试将失败,因为我的补丁没有像我预期的那样工作。我在这里做错了什么?如果 a
直接调用 b
而不是使用该词典,这绝对有效。我已经对此进行了测试。我知道你可以用 patch.dict
模拟字典,但我如何测试 b
被调用了?
所以我认为这是两个独立的单元测试,一个用于函数 a,一个用于字典 _actions。
_actions 不仅仅是一个简单的字典,而是某种意义上的动态函数调用。因此,如果您真的只是测试函数 a,那么您需要修补 _actions 对象并只测试函数范围内的功能。
_actions 不在测试范围内,应像任何其他方法一样单独测试。
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}
我试图用一个什么都不做的函数来模拟字典操作。相反,我应该将它模拟成一个 MagicMock
函数,这也是补丁的作用。
patch.dict(
'app.service._actions',
{'b': MagicMock} # MagicMock is imported from unittest.mock
)
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 }
我的测试将失败,因为我的补丁没有像我预期的那样工作。我在这里做错了什么?如果 a
直接调用 b
而不是使用该词典,这绝对有效。我已经对此进行了测试。我知道你可以用 patch.dict
模拟字典,但我如何测试 b
被调用了?
所以我认为这是两个独立的单元测试,一个用于函数 a,一个用于字典 _actions。
_actions 不仅仅是一个简单的字典,而是某种意义上的动态函数调用。因此,如果您真的只是测试函数 a,那么您需要修补 _actions 对象并只测试函数范围内的功能。
_actions 不在测试范围内,应像任何其他方法一样单独测试。
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}
我试图用一个什么都不做的函数来模拟字典操作。相反,我应该将它模拟成一个 MagicMock
函数,这也是补丁的作用。
patch.dict(
'app.service._actions',
{'b': MagicMock} # MagicMock is imported from unittest.mock
)