我想模拟生成SMTP客户端表单ScheduleEventFragments
。以下代码:
smtplib
返回
from smtplib import SMTP
from unittest.mock import patch
with patch('smtplib.SMTP') as smtp:
print(SMTP, smtp)
暗示修补程序失败。
编辑:有趣的是,Monkey Patching as described here会得到相同的结果。
<class 'smtplib.SMTP'> <MagicMock name='SMTP' id='140024329860320'>
答案 0 :(得分:2)
我几乎不做任何修补,但我相信你要修补得太晚,或者说错了。 SMTP
已导入,导致直接引用原始类 - 不再在smtplib
中查找它。相反,您需要修补该引用。让我们使用更实际的示例,其中包含module.py
和test_module.py
。
module.py
:
import smtplib
from smtplib import SMTP # Basically a local variable
def get_smtp_unqualified():
return SMTP # Doing a lookup in this module
def get_smtp_qualified():
return smtplib.SMTP # Doing a lookup in smtplib
test_module.py
import unittest
from unittest import patch
from module import get_smtp_unqualified, get_smtp_qualified
class ModuleTest(unittest.TestCase):
def test_get_smtp_unqualified(self):
with patch('module.SMTP') as smtp:
self.assertIs(smtp, get_smtp_unqualified())
def test_get_smtp_qualified_local(self):
with patch('module.smtplib.SMTP') as smtp:
self.assertIs(smtp, get_smtp_qualified())
def test_get_smtp_qualified_global(self):
with patch('smtplib.SMTP') as smtp:
self.assertIs(smtp, get_smtp_qualified())
只要你在查找之前及时修补,它就会做你想要的 - 3次通过测试。最早的时间是在导入除unittest
之外的任何其他模块之前。那些模块还没有导入smtplib.SMTP
。有关here的更多信息。但是,当你的测试分成多个模块时,它会变得棘手。
补丁本来就很脏。你正在搞乱另一个人的内部。为了使它工作,你必须在里面看。如果内部发生变化,测试将会中断。这就是为什么你应该把它作为最后的手段,并喜欢不同的手段,如依赖注入。这是一个完全不同的主题,但无论如何,不要依赖补丁来防止消息外出 - 也改变配置!