在Django单元测试中使用mock修补芹菜任务

2024-04-24 13:55:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图使用python模拟库来修补一个芹菜任务,该任务是在模型保存在我的django应用程序中时运行的,以确保它被正确调用。

基本上,任务是在myapp.tasks中定义的,并在my models.py文件的顶部导入,如下所示:

from .tasks import mytask

…然后使用mytask.delay(foo, bar)在模型内的save()上运行。到目前为止很好-当我真的在经营芹菜等的时候效果很好

我想构造一个模拟任务的单元测试,只是检查它是否用正确的参数被调用,而不是真正尝试运行芹菜任务。

所以在测试文件中,我在一个标准测试用例中得到了类似的东西:

from mock import patch # at the top of the file

# ...then later
def test_celery_task(self):
    with patch('myapp.models.mytask.delay') as mock_task:
        # ...create an instance of the model and save it etc
        self.assertTrue(mock_task.called)

……但它永远不会被调用/永远都是假的。我尝试过各种化身(改为修补myapp.models.mytask,并检查是否调用了mock_task.delay)。我从模拟文档中了解到导入路径是关键的,google告诉我它应该是在测试模块中看到的路径(如果我理解正确的话,应该是myapp.models.mytask.delay,而不是myapp.tasks.mytask.delay)。

我哪里做错了?修补芹菜有什么特别的困难吗?我可以修补celery.task(用作mytask的装饰器)吗?


Tags: 文件thefrom模型importtaskmodelssave
2条回答

装饰器@taskTask对象替换函数(请参见documentation)。如果您模拟任务本身,您将用MagicMock替换(有点神奇的)Task对象,它根本不会调度任务。相反,模拟Task对象的run()方法,如下所示:

@override_settings(CELERY_ALWAYS_EAGER=True)
@patch('monitor.tasks.monitor_user.run')
def test_monitor_all(self, monitor_user):
    """
    Test monitor.all task
    """

    user = ApiUserFactory()
    tasks.monitor_all.delay()
    monitor_user.assert_called_once_with(user.key)

你现在的问题与这是芹菜任务无关。你只是碰巧弄错了。;)

具体来说,您需要找出哪个视图或其他文件正在导入“mytask”,并在那里对其进行修补,因此相关行如下所示:

with patch('myapp.myview.mytask.delay') as mock_task:

这里还有更多的味道:

http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch

相关问题 更多 >