django - 直接调用绑定(bind)任务时的 Mocking Celery `self.request` 属性

标签 django unit-testing celery

我有一个任务foobar :

@app.task(bind=True)
def foobar(self, owner, a, b):
   if already_working(owner): # check if a foobar task is already running for owner.
       register_myself(self.request.id, owner) # add myself in the DB.
   return a + b

我如何模拟 self.request.id属性?我已经在修补所有内容并直接调用任务而不是使用 .delay/.apply_async ,但 self.request.id 的值好像是None (当我与 DB 进行真正的交互时,它会使测试失败,等等……)。

作为引用,我使用 Django 作为框架,但我认为这个问题是一样的,不管你使用的是什么环境。

最佳答案

免责声明 :嗯,我认为它没有记录在某个地方,这个答案可能取决于实现。

Celery 将他的任务打包到 celery.Task实例,我不知道它是否交换了 celery.Task.run通过用户任务功能或其他方法。

但是,当你直接调用任务时,你调用 __call__它会推送一个包含任务 ID 等的上下文……

所以想法是绕过__call__和 celery 通常的工作原理,首先:

  • 我们推送一个受控任务 ID:foobar.push_request(id=1)例如。
  • 然后,我们调用run方法:foobar.run(*args, **kwargs) .

  • 例子:
    @app.task(bind=True)
    def foobar(self, name):
        print(name)
        return foobar.utils.polling(self.request.id)
    
    @patch('foobar.utils.polling')
    def test_foobar(mock_polling):
        foobar.push_request(id=1)
        mock_polling.return_value = "done"
        assert foobar.run("test") == "done"
        mock_polling.assert_called_once_with(1)
    

    关于django - 直接调用绑定(bind)任务时的 Mocking Celery `self.request` 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47000371/

    相关文章:

    python - Celerybeat 计划多次执行任务?

    django - 将 celery 作为守护进程运行不会创建 PID 文件

    javascript - 使用 AJAX POST 发布数据

    python - 管理页面显示 django 中的错误

    django - 强制 django_compressor 重新编译 css/less 文件

    django - 什么可能导致 flatpages 中的 Page Not Found 错误?

    ruby-on-rails - 你最喜欢的 ruby​​ 和 rails 测试 "gem(s)"或 "plugins"

    unit-testing - xUnit Test Runner 无法通过 ReSharper 运行测试

    scala - akka:如何测试 Actor 是否被停止

    python - 在 Django 中使用 celerybeat 本地设置的正确方法是什么?