Как я могу издеваться над функцией, вызываемой из словаря? - PullRequest
2 голосов
/ 19 июня 2019

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 ]

1 голос
/ 20 июня 2019

Итак, я бы сказал, что это два отдельных модульных теста: один для функции 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}
0 голосов
/ 20 июня 2019

Я пытался смоделировать действие словаря с помощью функции, которая ничего не делает.Вместо этого я должен был смоделировать это для функции MagicMock, что также делает патч.

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