【问题标题】:Python testing: mocking a function that's imported AND used inside another funcitonPython 测试:模拟导入并在另一个函数中使用的函数
【发布时间】:2019-08-06 10:45:19
【问题描述】:

由于 Django 中的 Celery 任务常见的循环导入问题,我经常在我的方法中导入 Celery 任务,如下所示:

# some code omitted for brevity
# accounts/models.py
def refresh_library(self, queue_type="regular"):
    from core.tasks import refresh_user_library 

    refresh_user_library.apply_async(
        kwargs={"user_id": self.user.id}, queue=queue_type
    )
    return 0

在我对refresh_librarypytest 测试中,我只想测试refresh_user_library(Celery 任务)是用正确的argskwargs 调用的。但这不起作用:

# tests/test_accounts_models.py
@mock.patch("accounts.models.UserProfile.refresh_library.refresh_user_library")
def test_refresh_library():

错误是关于 refresh_library 没有属性 refresh_user_library

我怀疑这是因为任务(refresh_user_library) 是在函数本身中导入的,但我对模拟没有太多经验,所以这可能是完全错误的。

【问题讨论】:

  • 我认为你需要模拟 core.tasks.rehresh_user_library 而不是 accounts.models.UserProfile.refresh_library.refresh_user_library
  • @cagrias 谢谢你,嘲笑它(实际上,它的 apply_async)有效。我想我应该模拟使用它的对象而不是它定义的地方..?
  • Mocking 的意思是说:“我有这个要使用的外部包函数,只需忽略它并在调用它时返回这个值”。所以在你的情况下,外部包函数是core..tasks.rehresh_user_library.apply_sync
  • @cagrias 嗯,是的,但是这个函数不是在我的模型方法中使用的吗?无论如何,您已经回答了我的 OP 问题,您可以添加一个答案以便我标记为正确吗?

标签: python django pytest python-mock


【解决方案1】:

尽管apply_async 是您在core.tasks 中自己创建的函数,但如果您不想测试它而只想确保提供正确的参数,则需要模拟它。在您的问题中,您正在嘲笑错误的包裹。你应该这样做:

# tests/test_accounts_models.py
@mock.patch("core.tasks.rehresh_user_library.apply_sync")
def test_refresh_library():

【讨论】:

    【解决方案2】:

    在您的任务函数中,refresh_user_library 是本地名称,而不是任务的属性。您想要的是要模拟的函数的 real 限定名称:

    @mock.patch("core.tasks.refresh_user_library")
    def test_refresh_library():
        # you test here
    

    【讨论】:

      猜你喜欢
      • 2017-06-27
      • 1970-01-01
      • 2018-01-21
      • 2018-08-13
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多