在包__init__内修补函数,并在同一包内的模块内使用它

时间:2019-04-17 08:27:30

标签: python python-3.x pytest python-unittest

我正在尝试修补__init__.py中定义的内部包函数,该内部包函数由同一包内模块内部的函数所使用。我面临的问题是它没有被修补。

当我更改了模块内部的import语句时,我取得了一些成功,该模块使用的功能需要修补为绝对导入。问题是我不希望绝对导入,因此重构代码会很痛苦。

我的测试设置的结构是:

|- mylib
|  |- __init__.py
|  \- process.py
|- tests
|  \- test_process.py
|- setup.py

包装的初始化

# __init__.py
def store_info(info):
    raise ValueError('No connection!')

预期情况

# process.py
from . import store_info


def process_info(info):
    store_info(info)
# test_process.py
from unittest.mock import patch
import mylib.process


@patch('mylib.store_info')
def test_process_info(store_info_mock):
    info = "Some info"
    mylib.process.process_info(info)
    store_info_mock.assert_called_with(info)

当我将process.py中的导入从相对导入更改为绝对导入后,就会起作用。

# process.py
import mylib


def process_info(info):
    mylib.store_info(info)

使用类似import mylib的import语句,测试将通过适当的修补模拟程序通过。使用from . import store_data之类的语句,不会对该函数进行修补。

是否有可能使用相对导入并且仍然能够在同一软件包中修补功能?如果是这样,什么是好的做法?

1 个答案:

答案 0 :(得分:1)

您正在对声明的函数进行修补;相反,您应该在实际使用的地方打补丁。将装饰器更改为

@patch('mylib.process.store_info')
def test_process_info(store_info_mock):
    ...

请参阅stdlib文档中的Where to patch部分。