为了账号安全,请及时绑定邮箱和手机立即绑定

正确的mock.patch smtplib.SMTP方法

正确的mock.patch smtplib.SMTP方法

九州编程 2023-07-18 17:48:23
smtplib.SMTP.sendmail尝试在单元测试中模拟.修补调用。该sendmail方法似乎已成功模拟,我们可以将其查询为MagicMock,但sendmail 模拟的called和called_args属性未正确更新。看来我没有正确应用补丁。这是我正在尝试的一个简化示例:import unittest.mockwith 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和属性,但由于允许进行初始化,因此与主机建立了实际的 smtp 会话。这是单元测试,我不希望发生实际的网络。calledsmtplib.SMTP
查看完整描述

2 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超2个赞

我今天遇到了同样的问题,忘记了我正在使用上下文,所以只需更改


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)


查看完整回答
反对 回复 2023-07-18
?
Helenr

TA贡献1780条经验 获得超3个赞

我将 Dustymugs 的帖子标记为答案,但我发现了另一种技术来对依赖于模拟 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_)


查看完整回答
反对 回复 2023-07-18
  • 2 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信