Python 使用unittest.mock模拟类中使用的模块需要哪个目标?
我需要创建一个模块范围的夹具,在这里我模拟Python 使用unittest.mock模拟类中使用的模块需要哪个目标?,python,mocking,pytest,Python,Mocking,Pytest,我需要创建一个模块范围的夹具,在这里我模拟模块a和模块c在模块b.module\u b\u Class()中使用。我不能使用mock.patch注释,因为它提供了一个函数范围的mock,我还需要声明,当调用模块B_类时,在模块a上调用一个特定函数,在模块c上调用另一个函数。因此,我使用pytest案例将_解包到feature中,并编写了以下夹具: @pytest_cases.fixture_plus(scope="module", unpack_into="mock
模块a
和模块c
在模块b.module\u b\u Class()中使用。我不能使用mock.patch注释,因为它提供了一个函数范围的mock,我还需要声明,当调用模块B_类
时,在模块a
上调用一个特定函数,在模块c
上调用另一个函数。因此,我使用pytest案例将_解包到feature中,并编写了以下夹具:
@pytest_cases.fixture_plus(scope="module", unpack_into="mocked_module_a,mocked_module_b")
def my_fixture():
with mock.patch('my_top_module.my_sub_module.module_b.module_a') as module_a_mock:
with mock.patch('my_top_module.my_sub_module.module_b.module_c') as module_c_mock:
module_a_mock.my_func = MagicMock(return_value='Hello world')
module_c_mock.my_func_2 = MagicMock(return_value='Good morning')
但是,当我运行以下命令时:
def test_my_class(mocked_module_a, mocked_module_b):
my_class = Module_B_Class()
my_class.run()
mocked_module_a.assert_called_once()
mocked_module_b.assert_called_once()
是这样定义的
from my_top_module.my_sub_module import module_a
class Module_B_Class():
def run(self):
module_a.my_func()
module_c.my_func2()
调用的函数是原始函数,而不是替换的函数。我正在修补的目标是错误的吗?中描述了固定装置。基本原则是,yield
之前的代码在测试之前执行(或取决于范围、第一次测试之前、每个模块或每个测试类),而yield
之后的代码在测试之后执行(或最后一次测试、模块或类):
@pytest.fixture
定义我的固定装置():
do_设置()
产量
你要拆掉吗
当然,您也可以使用yield
返回值
对于上下文管理器,这意味着您必须在超出范围之前让步:
@pytest.fixture(scope=“module”)
定义我的固定装置():
使用mock.patch('my_top_module.my_sub_module.module_b.module_a')作为module_a_mock:
模块\u a\u mock.my\u func=MagicMock(返回\u value='Hello world')
屈服模
如果需要,现在可以通过测试中的fixture名称访问mock。在这种情况下,只有在执行当前模块中的测试之后,代码才会在屈服
后返回,因此在该点上,修补程序被恢复
在这种情况下,如果您不执行屈服
,那么在执行夹具时,您会立即超出范围,这意味着在您进行测试之前,补丁会被还原
更新:
以下是使用pytest\u案例的更新问题版本
:
@pytest\u cases.fixture\u plus(scope=“module”,
将模块解包为=“模拟模块a,模拟模块c”)
定义我的固定装置():
用mock.patch(
“my_top_module.my_sub_module.module_b.module_a”)作为模块a_mock:
用mock.patch(
“my_top_module.my_sub_module.module_b.module_c”)作为模块_c_mock:
模块\u a\u mock.my\u func=mock.MagicMock(返回\u value='Hello world')
模块\u c\u mock.my\u func2=mock.MagicMock(返回\u value='Good morning')
产量(模块a\U模拟、模块c\U模拟)
def测试我的课程(模拟模块a、模拟模块c):
my_class=模块_B_class()
我的班。跑()
mocked_module_a.my_func.assert_调用了_once()
mocked_module_c.my_func2.assert_called_once()
注意:为了避免混淆,我已将mocked_module_b
重命名为mocked_module_c
。另外,assert\u called\u once
在模块上而不是函数上被调用。是module\u a
和module\u b
位于my\u top\u模块下。my\u sub\u模块
正确,它们是H,您的夹具中似乎缺少了屈服
(还有run
中的self
参数,但这可能是一个输入错误).除此之外,我觉得还可以。你能告诉我夹具应该如何使用收益率的文档吗?太棒了。这很有意义,我唯一的问题是,实际上我有两个模拟,我使用pytest用例和fixture_plus来解包,但使用生成器和解包会产生一个错误:(要解包的元组)source_fixture_value=kwargs.pop(source_f_name)#解包:在正确的位置获取项。>返回source_fixture_value[_value_idx]E TypeError:“generator”对象不是subscripta现在应该更有意义了,我已经更新了问题,使其更加精确和清晰。好的,我更新了答案。不知道pytest\u案例
-非常方便!让我试试。我认为generator和pytest案例有问题