unittest celery task assertRaises

时间:2017-01-12 20:04:39

标签: python unit-testing celery assert

我有一些芹菜任务。我想通过unittest进行测试。

我正在做一些非常类似的事情:

class TestMe(unittest.TestCase):
    def test_celery_task(self):
        self.assertRaises(ValueError, celery_task.apply, args)

对我来说有点奇怪:

这个断言失败了,因为ValueError not raised,但在执行过程中我可以看到这个芹菜任务的结果是ValueError。

我不确定,但看起来断言检查的速度比ValueError快。 是否有可能检查执行芹菜任务的结果? 或者如何测试?

2 个答案:

答案 0 :(得分:0)

那不可能奏效。当您将Celery任务排入队列时,所有发生的事情就是您将一条消息放入队列中以便单独获取一个进程;正是该进程运行任务,并可能引发异常。

如果你想检查任务本身是否引发了ValueError,那么你应该调用任务,而不是延迟函数:

self.assertRaises(ValueError, celery_task, args)

答案 1 :(得分:0)

我在这里看到3个选项。

1)尝试在apply()上调用get()。您将获得以下内容:

class TestMe(unittest.TestCase):
    def test_celery_task(self):
        self.assertRaises(ValueError, celery_task.apply().get(), args)

2)您可以通过设置'task_always_eager'来启用预备模式。到True,但不保证您的代码能够赶上。

3)更好的选择是嘲笑芹菜任务。从单元测试的角度来看,用实际的“活着”来测试一个代码单元实际上是不正确的。像芹菜这样的系统的一部分。 以下是从芹菜testing documentation中获取的代码示例。

from pytest import raises

from celery.exceptions import Retry

# for python 2: use mock.patch from `pip install mock`.
from unittest.mock import patch

from proj.models import Product
from proj.tasks import send_order

class test_send_order:

    @patch('proj.tasks.Product.order')  # < patching Product in module above
    def test_success(self, product_order):
        product = Product.objects.create(
            name='Foo',
        )
        send_order(product.pk, 3, Decimal(30.3))
        product_order.assert_called_with(3, Decimal(30.3))

    @patch('proj.tasks.Product.order')
    @patch('proj.tasks.send_order.retry')
    def test_failure(send_order_retry, product_order):
        product = Product.objects.create(
            name='Foo',
        )

        # set a side effect on the patched method
        # so that it raises the error we want.
        product_order.side_effect = OperationalError()

        with raises(Retry):
            send_order(product.pk, 3, Decimal(30.6))