我需要模拟一个在 python 类的类属性中调用的函数。我可以在对象初始化时修补函数,但是当我在不创建实例的情况下访问它时它不起作用。请参阅下面的代码:
# methods.py
def bar():
return "bar"
# foo.py
from methods import bar
class Foo:
class_attribute = bar()
def __init__(self):
self.class_attribute = bar()
#test_foo.py
from foo import Foo
import unittest
from unittest.mock import patch
class FooTestCase(unittest.TestCase):
@patch("foo.bar")
def test_mock_foo(self, mock):
mock.return_value = "patched foo"
print(Foo.class_attribute) # it prints "bar"
print(Foo().class_attribute) # it prints "patched foo"
unittest.main(argv=[''], verbosity=0,exit=False)
如何在不模拟类属性的情况下模拟函数?
正如 @jonrsharpe 在评论中所说,在您的情况下,该函数是在模块加载时(即在模拟之前)的类 definition 时调用的。因此,在运行测试和修补函数时,类变量已经保存了该值。
mock.patch
在给定模块中查找对象并用 Mock 替换该对象。您需要使用 mock.patch.object
修补对象本身,然后使用 importlib 重新加载模块。
import importlib
from unittest import mock
import foo
import methods
def test_mock_foo(self):
expected_value = "patched foo"
with mock.patch.object(target=methods, attribute="bar", return_value="patched foo"):
importlib.reload(module=foo)
assert foo.Foo.class_attribute == expected_value
assert foo.Foo().class_attribute == expected_value