我正在尝试为send_email
编写测试:
def send_email(email_info):
user_name, user_email, message = email_info
recipient = f'{user_name} <{user_email}>'
message = format_email(message, UNAME, recipient)
context = ssl.create_default_context()
with smtplib.SMTP(SERVER, PORT) as server:
server.starttls(context=context)
server.login(UNAME, PASSWORD)
server.send_message(message)
return
send_email
在我的项目子目录<project_name>/base/tasks
中。
这是我的测试尝试:
import mock
from pytest_mock import mocker
class TestEmailFunctions:
@mock.patch('<project_name>.base.tasks.smtplib')
def test_send_email(self, mock_smtp, mocker):
server = mocker.MagicMock()
server.starttls = mocker.MagicMock()
server.login = mocker.MagicMock()
server.send_message = mocker.MagicMock()
mock_smtp.SMTP = mocker.MagicMock()
mock_smtp.SMTP.return_value = server
msg = {'subject': "Hi, Elmo!", 'body':"It's Grover!"}
send_email(('Elmo', 'elmo@sesamestreet.org', msg))
mock_smtp.SMTP.assert_called_once()
server.login.assert_called_once()
assert server.login.call_args[0] == 'Elmo'
server.send_message.assert_called_once()
assert server.send_message.call_args == 'Hi, Elmo!'
mock_smtp.SMTP.assert_called_once()
通过,因此我知道可以通过SMTP方法正确处理模拟。但是server.login.assert_called_once()
失败:AssertionError: Expected 'login' to have been called once. Called 0 times.
我在多个不同的地方插入了一个断点,但是跳到了最有影响力的地方-我在以其参数调用server.login()
之后,在函数本身而不是测试中放置了一个断点:< / p>
-> server.send_message(message)
(Pdb) server
<MagicMock name='mock().__enter__()' id='4581656560'>
(Pdb) server.login
<MagicMock name='mock().__enter__().login' id='4581885096'>
(Pdb) server.login.mock_calls
[call('<our email>', '<email password>')]
似乎我正确地设置了模拟,所以我茫然地知道为什么mock_smtp.SMTP.assert_called_once()
通过但server.login.assert_called_once()
失败。也许与with
语句有关?如果有人可以提供有关测试此功能的正确方法的解释和建议,我将不胜感激。