简体   繁体   English

如何模拟在类方法中使用的外部函数?

[英]How can I mock external function that is used in class method?

I want to mock a function that is used in some method. 我想模拟某个方法中使用的函数。 This function is located in other module. 此功能位于其他模块中。

How can I do that? 我怎样才能做到这一点?

Tried this option, but it does not work. 尝试了此选项,但是它不起作用。

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

I want SomeClass().foo() to execute my mock_return() inside instead of my_function() . 我希望SomeClass().foo()而不是my_function()在内部执行我的mock_return() my_function()

You can use unittest.mock.patch or the pytest-mock plugin with the mocker fixture. 您可以将unittest.mock.patchpytest-mock插件与mocker夹具一起使用。

Your package 你的包裹

pack/another_pack.py : pack/another_pack.py

from pack import utils

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

pack/utils.py : pack/utils.py

def my_function():
    return 'original'

Tests 测验

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

Note that in all tests the first argument of patch is the name of the module where you want to mock the function ( pack.another_pack ) with the name of the function how it appears in the module ( utils.my_function ). 请注意,在所有测试中, patch的第一个参数是要在其中模拟函数的模块名称( pack.another_pack ),以及函数名称在模块中的显示方式( utils.my_function )。

my_function is mocked for the entire pack.another_pack module. 整个pack.another_pack模块都pack.another_pack my_function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM