Макет не работает над функцией модуля

Я написал функцию send_formatted_email, которая форматирует тему и сообщение электронной почты, а затем вызывает функцию send_email в отдельном модуле.

Теперь я должен проверить, что send_formatted_email вызывает send_email с ожидаемыми аргументами. Для этой цели я пытаюсь издеваться над send_email, используя patch, но над ним не издеваются.

test.py

@patch('app.util.send_email')
def test_send_formatted_email(self, mock_send_email):
    mock_send_email.return_value = True
    response = send_formatted_email(self.comment, to_email)
    mock_send_email.call_args_list
    ....

просмотры.py

def send_formatted_email(comment, to_email):
    ...
    message = comment.comment
    subject = 'Comment posted'
    from_email = comment.user.email
    ...
    return send_email(subject, message, to_email, from_email)

util.py

def send_email(subject, message, to, from):
    return requests.post(
        ...
    )

Я даже пробовал app.util.send_email = MagicMock(return_value=True), но и это не сработало. Любая идея, что я делаю неправильно?


person Afnan Nazir    schedule 14.08.2016    source источник
comment
Вы исправляете там, где функция используется, а не там, где она определена. Попробуйте @patch('app.views.send_email')   -  person jonrsharpe    schedule 14.08.2016
comment
comment
@jonrsharpe Спасибо, это сработало.   -  person Afnan Nazir    schedule 14.08.2016
comment
В свете вашего ответа теперь я могу исправить, где определена функция, если я импортирую модуль вместо самой функции.   -  person Afnan Nazir    schedule 14.08.2016
comment
Возможный дубликат патча Python mock не работает должным образом для общедоступного метода   -  person funky-future    schedule 25.05.2017


Ответы (2)


Как уже упоминалось jonrsharpe, уже есть ответ в еще один вопрос.

В моем случае я не смог использовать ни одну из предложенных альтернатив (перезагрузка или исправление моего собственного модуля).

Но сейчас я просто импортирую нужный метод прямо перед использованием:

def send_formatted_email(comment, to_email):
    ...
    message = comment.comment
    subject = 'Comment posted'
    from_email = comment.user.email
    ...
    from app.util import send_email
    return send_email(subject, message, to_email, from_email)

Это загрузит метод модуля после того, как вы его исправили.

Минусы:

  • Импорт выполняется перед каждым вызовом метода.
person Eruvanos    schedule 03.05.2017

Попробуй это:

import app.util

...

return util.send_email(subject, message, to_email, from_email)

or:

@patch('app.views.send_email')

...

return send_email(subject, message, to_email, from_email)
person Suchy    schedule 18.05.2020