Python:Mock 在 celery 任务中不起作用

Nik*_*lub 3 python django unit-testing mocking celery

我想使用 pythonmock库来测试我的 Django 应用程序发送电子邮件。

测试代码:

# tests.py
from django.test import TestCase

class MyTestCase(TestCase):

    @mock.patch('django.core.mail.mail_managers')
    def test_canceled_wo_claiming(self, mocked_mail_managers):
        client = Client()
        client.get('/')
        print(mocked_mail_managers.called)
        mocked_mail_managers.assert_called_with('Hi, managers!', 'Message Body')
Run Code Online (Sandbox Code Playgroud)

第一个例子 - 没有任务

# views.py
from django.views.generic import View
from django.core.mail import mail_managers

class MyView(View):

    def get(self, request):
        mail_managers('Hi, managers!', 'Message Body')
        return HttpResponse('Hello!')
Run Code Online (Sandbox Code Playgroud)

第二个例子 - 有任务

# views.py
from django.views.generic import View
from . import tasks

class MyView(View):
    def get(self, request):
        tasks.notify.apply_async()
        return HttpResponse('Hello!')


# tasks.py
from celery import shared_task
from django.core.mail import mail_managers

@shared_task
def notify():
    mail_managers('Hi, managers!', 'Message Body')
Run Code Online (Sandbox Code Playgroud)

第一个示例正常工作,第二个示例失败,但有Not called异常。

我的设置:

# Celery
BROKEN_URL = 'memory://'
BROKER_BACKEND = 'memory'

CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner'
Run Code Online (Sandbox Code Playgroud)

是否有可能进行这样的集成测试,或者解决这个问题的唯一方法是将测试一分为二?

Nik*_*lub 6

我发现了一个问题,这很愚蠢。此处此处描述

基本原则是在查找对象的位置打补丁,该位置不一定与定义的位置相同。

我需要改变:

@mock.patch('django.core.mail.mail_managers')
Run Code Online (Sandbox Code Playgroud)

@mock.patch('path.to.tasks.mail_managers')
Run Code Online (Sandbox Code Playgroud)