整个测试会话的模拟补丁

问题描述 投票:0回答:1

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
我怎样才能让模拟补丁超出一个函数的范围?

python python-unittest python-mock python-unittest.mock
1个回答
0
投票
start

。仅调用 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

© www.soinside.com 2019 - 2024. All rights reserved.