Mocking a Celery task call in Python with patch
使用模拟的返回值修补Celery任务调用将返回
这是我修补Celery任务的单元测试:
1 2 3 4 5 6 7 8 9 10 | 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 |
这是正在测试的功能:
1 2 3 4 5 6 7 8 | 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']: ... |
最后一行引发
为什么我可以在单元测试中调用mock_task.get(),但从
不幸的是,我对Celery几乎一无所知,但是看起来问题出在嘲弄。
你有:
1 | tasks.my_task.delay('input from foo').get() |
在
1 | mock_task('input from foo').get() |
这与以下内容不同:
1 | mock_task.get() |
您应该将模拟创建更改为:
1 | mock_task().get = Mock(return_value={'success': True}) |
当您访问现有的Mock属性或调用它时,默认情况下会创建新的Mock实例。 所以我们可以简化一下:
1 | mock_task().get.return_value = {'success': True} |