tl;dr 如何让
mock.patch
持续整个测试会话,而不是仅在 @classmethod
范围或函数范围内?我想模拟补丁一个类方法。但是,我想在每个测试中运行 with
一次而不是一次。
patch.object
两次
patch.object
但是,我只想打一次
class MyClass():
@classmethod
def print_hello(cls):
print("hello from the real MyClass.print_hello")
def do_something(self):
pass
def mock_print_hello(_cls):
print("hello from the patched mock_print_hello")
class TestMyClass(unittest.TestCase):
def test_init(self):
with mock.patch.object(MyClass, "print_hello", new_callable=mock_print_hello) as patch:
MyClass.print_hello()
MyClass()
def test_do_something(self):
with mock.patch.object(MyClass, "print_hello", new_callable=mock_print_hello) as patch:
MyClass.print_hello()
MyClass().do_something()
一次:
patch.object
实际上,在
class MyClass():
@classmethod
def print_hello(cls) :
print("hello from the real MyClass.print_hello")
def do_something(self):
pass
def mock_print_hello(_cls):
print("hello from the patched mock_print_hello")
class TestMyClass(unittest.TestCase):
@classmethod
def setUpClass(cls):
# this patch will not remain after setUpClass returns
patch = mock.patch.object(MyClass, "print_hello", new_callable=mock_print_hello)
def test_init(self):
# this calls the real MyClass.print_hello, not mock_print_hello
MyClass.print_hello()
MyClass()
def test_do_something(self):
# this calls the real MyClass.print_hello, not mock_print_hello
MyClass.print_hello()
MyClass().do_something()
内修补
MyClass.new
不会持续超出功能范围。换句话说,setUpClass
和test_init
不调用test_do_something
,它们调用mock_print_hello
。我怎样才能让模拟补丁超出一个函数的范围?
。仅调用 MyClass.print_hello
或
patch
返回修补程序对象,它不会开始修补。由于您无法在设置代码中使用装饰器或上下文管理器,因此您必须在相应的 setUp/tearDown 方法中启动/停止修补程序:
patch.object
如果您需要修补整个模块,您可以在相应的模块功能中执行相同的操作:
class TestMyClass(unittest.TestCase):
patcher = None
@classmethod
def setUpClass(cls):
cls.patcher = mock.patch.object(MyClass, "print_hello", new_callable=mock_print_hello)
cls.patcher.start()
@classmethod
def tearDownClass(cls):
cls.patcher.stop()
顺便说一句,如果您要使用
patcher = None
def setUpModule():
global patcher
patcher = mock.patch.object(...)
patcher.start()
def tearDownModule():
patcher.stop()
而不是
pytest
,也可以使用固定装置中的上下文管理器来完成:unittest
或在模块情况下:
class MyClassTest:
@pytest.fixture(scope="class", autouse=True)
def setup(self):
with mock.patch.object(MyClass, "print_hello", new_callable=mock_print_hello):
yield