【发布时间】:2023-03-28 06:51:01
【问题描述】:
我只是在学习 unittest Mocks 并试图了解为什么修补对“smtplib.SMTP”的调用不会返回在模拟对象上设置的值。我认为不是,因为断言失败了。
我对发送电子邮件的函数有一个简单的定义:
def send(sender, to, subject="None", body="None", server="localhost"):
message = email.message.Message()
message['To'] = to
message['From'] = sender
message['Subject'] = subject
message.set_payload(body)
server = smtplib.SMTP(server)
try:
server.sendmail(sender, to, message.as_string())
finally:
server.quit()
我有一个包含简单测试函数的单元测试文件:
def test_send():
with patch('smtplib.SMTP') as mock:
instance = mock.return_value
instance.sendmail.return_value = {}
res = send('x@gmail.com', 'y@gmail.com', 'subject', 'body')
assert res == {}
据我了解,当调用 'smtplib.SMTP' 的 sendmail 时,该调用应由 mock 修补,并应返回一个空字典。所以 res 变量应该设置为 {}。
对文件执行 pytest 时,断言总是失败:
assert None == {}
我有两个问题:
- 我对单元测试的定义有问题吗?
- 什么是调试此类问题的好方法。我尝试使用 --trace 选项运行 pytest,但在单步执行代码时无法捕捉到“修补”时刻。
【问题讨论】:
-
你能分享你的文件树吗?
-
patch需要根据您要修补的上下文来指定要修补的东西。send是在与test_send相同的文件中定义的,还是在另一个文件/模块中定义的? -
send在导入到测试模块的不同模块中定义。我不认为这是一个问题,因为在与测试它们的模块不同的模块中定义函数是正常的。 -
能否请您在代码 sn-p 中添加模拟的导入语句,以便更好地理解模块。谢谢
标签: python mocking pytest python-unittest