Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Mock doesn't work inside celery task [duplicate]

I want to use python mock library for testing that my Django application sends email.

Test code:

# 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')

First example - without tasks

# 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!')

Second example - with tasks

# 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')

The first example works normal, second example fails, with Not called exception.

My settings:

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

CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner'

Is it possible to perform such integrated test or the only way to solve this problem is split test into two?

like image 757
Nikolai Golub Avatar asked Aug 30 '25 18:08

Nikolai Golub


1 Answers

I found a problem and it was pretty silly. Described here and Here:

The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.

I need to change:

@mock.patch('django.core.mail.mail_managers')

with

@mock.patch('path.to.tasks.mail_managers')
like image 75
Nikolai Golub Avatar answered Sep 02 '25 08:09

Nikolai Golub