如何解决正确的模仿方法.smtplib.SMTP
尝试模拟。在单元测试中修补对smtplib.SMTP.sendmail
的调用。 sendmail
方法似乎已被成功模拟,我们可以将其查询为MagicMock
,但是sendmail模拟的called
和called_args
属性没有正确更新。似乎我没有正确应用补丁。
这是我正在尝试的简化示例:
import unittest.mock
with unittest.mock.patch('smtplib.SMTP',autospec=True) as mock:
import smtplib
smtp = smtplib.SMTP('localhost')
smtp.sendmail('me','me','hello world\n')
mock.assert_called() # <--- this succeeds
mock.sendmail.assert_called() # <--- this fails
此示例生成:
AssertionError: Expected 'sendmail' to have been called.
如果我将补丁更改为smtp.SMTP.sendmail
;例如:
with unittest.mock.patch('smtplib.SMTP.sendmail.',autospec=True) as mock:
...
在这种情况下,我可以成功访问模拟的called_args
和called
属性,但是由于允许进行smtplib.SMTP
初始化,因此可以使用以下命令建立实际的smtp会话:主持人。这是单元测试,我希望没有实际的联网。
解决方法
我今天遇到了同样的问题,却忘记了我正在使用上下文,所以只需更改
mock.sendmail.assert_called()
到
mock.return_value.__enter__.return_value.sendmail.assert_called()
这看起来很混乱,但这是我的示例:
msg = EmailMessage()
msg['From'] = 'no@no.com'
msg['To'] = 'no@no.com'
msg['Subject'] = 'subject'
msg.set_content('content');
with patch('smtplib.SMTP',autospec=True) as mock_smtp:
misc.send_email(msg)
mock_smtp.assert_called()
context = mock_smtp.return_value.__enter__.return_value
context.ehlo.assert_called()
context.starttls.assert_called()
context.login.assert_called()
context.send_message.assert_called_with(msg)
,
我将ustrymuugs的帖子标记为答案,但是我发现了另一种技术来对依赖于模拟method_calls的呼叫进行单元测试。
import unittest.mock
with unittest.mock.patch('smtplib.SMTP',autospec=True) as mock:
import smtplib
smtp = smtplib.SMTP('localhost')
smtp.sendmail('me','you','hello world\n')
# Validate sendmail() was called
name,args,kwargs = smtpmock.method_calls.pop(0)
self.assertEqual(name,'().sendmail')
self.assertEqual({},kwargs)
# Validate the sendmail() parameters
from_,to_,body_ = args
self.assertEqual('me',from_)
self.assertEqual(['you'],to_)
self.assertIn('hello world',body_)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。