Python 测试:模拟导入并在另一个函数中使用的函数

Python testing: mocking a function that's imported AND used inside another funciton

由于 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 测试中,我只想测试是否使用正确的 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

我怀疑这是因为 task(refresh_user_library) 是在函数本身中导入的,但我对 mocking 的经验不多,所以这可能是完全错误的。

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

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

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

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