Mocking out a call within a celery task
我有一个运行芹菜任务的烧瓶应用程序。 我正在尝试模拟在该任务中发生的单个API调用。
views.py
1 2 3 4 5 | from mypackage.task_module import my_task @app.route('/run_task') def run_task(): task = my_task.delay() return some_response |
task_module.py
1 2 3 4 5 | from mypackage.some_module import SomeClass @celery.task def my_task(): return SomeClass().some_function() |
some_module.py
1 2 3 4 5 6 7 8 9 | from mypackage.xyz import external_service class SomeClass(object): def some_function(self): #do some stuff result = external_service(some_param) if 'x' in result: #do something elif 'y' in result: #do something else |
我想模拟
所以这就是我正在尝试的:
1 2 3 4 | @mock.patch('mypackage.some_module.external_service', autospec=True) def test_x_path(my_mock): my_mock.return_value = {'x': some_val} #run test, expect 'x' code path to run |
但是,这是行不通的,因为(我认为)该修补程序发生在Flask的Python进程中,而不是Celery正在使用的修补程序。 模拟任务本身不起作用,因为我要测试的是外部服务返回
帮助将不胜感激。
一个不错的选择是在测试配置中将
附带的好处是,您无需拥有Celery工人,因此简化了测试配置。
更新:在评论中进行讨论后,您似乎不想或不能摆脱Celery工作人员进行测试配置。在这种情况下,我可以提供三种解决方案,我认为它们可以满足您的需求:
编写一个模拟您的Celery任务的远程控制命令,然后使测试代码通过broadcast()在所有工作程序上运行。
为您的工作人员定义一个自定义命令行选项,例如
创建一个替代模块,以在
我希望您能找到这三个选项之一!
创建测试功能设置
1 2 3 4 5 6 7 8 | class TestCeleryTask(TestCase): def setUp(self): app.config['CELERY_ALWAYS_EAGER'] = True app.config['BROKER_BACKEND'] = 'memory' app.config['CELERY_EAGER_PROPAGATES_EXCEPTIONS'] = True def test_task(self): # test it |