在 class 方法中模拟第三方函数
Mocking third-party function inside class method
这可能是一个小问题,但我找不到合适的解决方案,而且我不明白如何解决它。我简化了问题,所以我有两个文件 my_module.py
和 test_module.py
在同一本地化。
import numpy as _np
class MyClass:
def __init__(self) -> None:
self.attribute = 1
self.method()
def method(self) -> None:
arr = _np.arange(9).reshape(-1, 3)
self.attribute = 2
from unittest.mock import Mock, patch
import pytest
from my_module import MyClass
@pytest.fixture
def init_mock():
with patch.object(MyClass, '__init__', return_value=None) as init:
yield init
@pytest.fixture
def method_mock():
with patch.object(MyClass, 'method') as method:
yield method
@pytest.fixture
def my_class_init_mock(init_mock):
yield MyClass()
@pytest.fixture
def my_class_method_mock(method_mock):
yield MyClass()
def test_init(my_class_method_mock):
assert my_class_method_mock.attribute == 1
def test_method(my_class_init_mock):
my_class_init_mock.method()
assert my_class_init_mock.attribute == 2
两项测试全部通过。此外,我需要检查 _np.arange(9).reshape
是否使用 -1, 3
参数调用过一次。我发现我应该从my_module.py
直接引用numpy
。我试图在上次测试上方添加 @patch('my_module._np')
。我还尝试将模块的fixture传递给my_class_method_mock
的fixture。不幸的是,当我触发 .method()
函数时,我无法调用这个模拟。如何在它们之间建立联系?
这可以通过定义 _np
的夹具并检查是否调用了此模拟来实现:
@pytest.fixture
def numpy_mock():
with patch('my_module._np') as numpy:
yield numpy
...
def test_method(my_class_init_mock, numpy_mock):
my_class_init_mock.method()
numpy_mock.arange.assert_called_once_with(9)
numpy_mock.arange().reshape.assert_called_once_with(-1, 3)
assert my_class_init_mock.attribute == 2
请注意,我们可以断言方法链接的每一部分。
这可能是一个小问题,但我找不到合适的解决方案,而且我不明白如何解决它。我简化了问题,所以我有两个文件 my_module.py
和 test_module.py
在同一本地化。
import numpy as _np
class MyClass:
def __init__(self) -> None:
self.attribute = 1
self.method()
def method(self) -> None:
arr = _np.arange(9).reshape(-1, 3)
self.attribute = 2
from unittest.mock import Mock, patch
import pytest
from my_module import MyClass
@pytest.fixture
def init_mock():
with patch.object(MyClass, '__init__', return_value=None) as init:
yield init
@pytest.fixture
def method_mock():
with patch.object(MyClass, 'method') as method:
yield method
@pytest.fixture
def my_class_init_mock(init_mock):
yield MyClass()
@pytest.fixture
def my_class_method_mock(method_mock):
yield MyClass()
def test_init(my_class_method_mock):
assert my_class_method_mock.attribute == 1
def test_method(my_class_init_mock):
my_class_init_mock.method()
assert my_class_init_mock.attribute == 2
两项测试全部通过。此外,我需要检查 _np.arange(9).reshape
是否使用 -1, 3
参数调用过一次。我发现我应该从my_module.py
直接引用numpy
。我试图在上次测试上方添加 @patch('my_module._np')
。我还尝试将模块的fixture传递给my_class_method_mock
的fixture。不幸的是,当我触发 .method()
函数时,我无法调用这个模拟。如何在它们之间建立联系?
这可以通过定义 _np
的夹具并检查是否调用了此模拟来实现:
@pytest.fixture
def numpy_mock():
with patch('my_module._np') as numpy:
yield numpy
...
def test_method(my_class_init_mock, numpy_mock):
my_class_init_mock.method()
numpy_mock.arange.assert_called_once_with(9)
numpy_mock.arange().reshape.assert_called_once_with(-1, 3)
assert my_class_init_mock.attribute == 2
请注意,我们可以断言方法链接的每一部分。