我有一个代码库(如下所示),其中有一个包含我开发的代码的src目录,以及tp中的一些支持第三方库。
.
├── src
│ ├── f.py
│ └── __init__.py
├── tp
│ ├── __init__.py
│ └── sim.py
│
└── tests
# contents of src/f.py
#!/usr/bin/python
from tp.sim import sim
def somefunc():
sim()
# contents of tp/sim.py
#!/usr/bin/python
def sim():
print("Hello, I'm in sim.sim()")
我打算为src目录中的代码编写测试。在示例文件中可见,src目录中的代码依赖于tp中的文件。对于tp中的大多数函数,我打算将它们monkeypatch
用于测试。测试文件的示例如下所示。
1 #!/usr/bin/python
2
3
4 import src
5 from src.f import somefunc
6 from tp.sim import sim
7
8
9 def deco(func):
10 def wrapper(*args, **kwargs):
11 print("I'm inside wrapper")
12 func(*args, **kwargs)
13
14 return wrapper
15
16
17 sim = deco(sim)
18
19 # setattr(src.f, 'sim', sim)
20 somefunc()
在上面的代码中,当monkeypatchingtp.sim.sim
时,不会影响src.f.somefunc
的行为(第20行)。只有当我们明确地修补名称空间src.f.sim
中的函数sim
(第19行)时,我们才会看到修补的函数。
我在src目录中有多个文件,这些import
文件来自tp和src,而这些文件又来自tp文件中的import
。
我的主要问题是,我如何确保我的猴痘修补函数始终是测试过程中使用的函数(即,如果我在测试设置中用mysim()
修补tp.sim.sim()
,那么该范围内的所有测试都会看到mysim()
)
如果您的测试代码导入:
from tp.sim import sim
f
模块将具有指向sim
函数的全局sim
名称。在tp.sim
的全局中更改sim
不会神奇地更新模块f
中的全局名称sim
,因此f.sim
将始终指向实函数。
因此,如果您想在不更改导入的情况下对sim
函数进行猴痘修补,您可以尝试修补f
模块的全局sim
名称,意思是:src.f.sim
。
将f
中的导入更改为:会更容易理解
from tp import sim
在这种情况下,src.f
获得指向sim
模块的sim
全局名称,该模块中的函数可以通过当前的修补方法进行修改。没有重复的sim
函数名,没有意外。