如何模拟从字典调用的函数?

时间:2019-06-19 18:46:17

标签: python django unit-testing pytest python-unittest

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被调用了?

2 个答案:

答案 0 :(得分:1)

所以我认为这是两个单独的单元测试,一个用于功能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}

答案 1 :(得分:0)

我试图用不执行任何操作的函数来模仿字典动作。相反,我应该将其嘲笑为MagicMock函数,这也是补丁程序的功能。

patch.dict(
    'app.service._actions',
    {'b': MagicMock} # MagicMock is imported from unittest.mock
)