Как я могу смоделировать внешнюю функцию, которая используется в методе класса? - PullRequest
0 голосов
/ 06 июля 2019

Я хочу смоделировать функцию, которая используется в каком-то методе. Эта функция находится в другом модуле.

Как я могу это сделать?

Пробовал эту опцию, но она не работает.

from pack import utils
from pack.another_pack import SomeClass

@pytest.mark.parametrize('attr', ['a', 'b', 'c'])
def test_foo_bar(attr, monkeypatch):
    def mock_return():
        return attr
    monkeypatch.setattr(utils, 'my_function', mock_return)
    SomeClass().foo()  # this foo() function uses my_function inside that I want to mock

Я хочу, чтобы SomeClass().foo() выполнил мой mock_return() внутри вместо my_function().

1 Ответ

1 голос
/ 06 июля 2019

Вы можете использовать unittest.mock.patch или pytest-mock плагин с приспособлением mocker.

Ваш пакет

pack/another_pack.py:

from pack import utils

class SomeClass:
    def foo(self):
        return utils.my_function()

pack/utils.py:

def my_function():
    return 'original'

Тесты

import pytest
from unittest.mock import patch
from pack.another_pack import SomeClass


# Replace my_function with another function. You could pass parameters
# to the mocked function and handle them in the replacement.
@pytest.mark.parametrize("attr", ["a", "b", "c"])
def test_replace(attr):
    def mock_return():
        return attr

    with patch("pack.another_pack.utils.my_function", new=mock_return):
        assert SomeClass().foo() == attr


# If you just want to override the return value.
@pytest.mark.parametrize("attr", ["a", "b", "c"])
def test_return_value(attr):
    with patch("pack.another_pack.utils.my_function") as my_func:
        my_func.return_value = attr
        assert SomeClass().foo() == attr


# With the pytest-mock plugin and the mocker fixture instead of unittest.mock.
@pytest.mark.parametrize("attr", ["a", "b", "c"])
def test_mock_plugin(attr, mocker):
    my_func = mocker.patch("pack.another_pack.utils.my_function")
    my_func.return_value = attr
    assert SomeClass().foo() == attr

Обратите внимание, что во всех тестах первым аргументом patch является имямодуль, в котором вы хотите смоделировать функцию (pack.another_pack) с именем функции, как она выглядит в модуле (utils.my_function).

my_function смоделирована для всего модуля pack.another_pack.

...