Petrus Theron
Petrus Theron

Reputation: 28807

Mocking a Celery task call in Python with patch

Patching a Celery task call with a mocked return value returns <Mock name='mock().get()' ...> instead of the expected return_value defined by mock_task.get.return_value = "value". However, the mocked task functions correctly within my unit test.

Here is the unit test where I am patching my Celery task:

def test_foo(self):

    mock_task = Mock()
    mock_task.get = Mock(return_value={'success': True})

    print mock_task.get() # outputs {'success': True}

    with patch('app.tasks.my_task.delay', new=mock_task) as mocked_task:
        foo()  # this calls the mocked task with an argument, 'input from foo'
        mock_tasked.assert_called_with('input from foo')  # works

And here is the function being tested:

def foo():
    print tasks.my_task.delay  # shows a Mock object, as expected
    # now let's call get() on the mocked task:
    task_result = tasks.my_task.delay('input from foo').get()
    print task_result  # => <Mock name='mock().get()' id='122741648'>
    # unexpectedly, this does not return {'success': True}
    if task_result['success']:
        ...

The last line raises TypeError: 'Mock' object has no attribute '__getitem__'

Why can I call mock_task.get() from within my unit test, but calling it from foo returns a <Mock ...> instead of the expected return value?

Upvotes: 8

Views: 4696

Answers (1)

and
and

Reputation: 2092

Unfortunately I know almost nothing about Celery, but it looks like the problem is with mocking.

You have:

tasks.my_task.delay('input from foo').get()

After patch('app.tasks.my_task.delay', new=mock_task) it becomes:

mock_task('input from foo').get()

Which is not the same as:

mock_task.get()

You should change your mock creation to:

mock_task().get = Mock(return_value={'success': True})

New Mock instance is created by default when you access existing Mock attribute or call it. So we can simplify it a little:

mock_task().get.return_value = {'success': True}

Upvotes: 8

Related Questions