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案例有问题