【问题标题】:Unit test Flask view mocking out celery tasks单元测试 Flask 视图模拟 celery 任务
【发布时间】:2013-06-16 10:40:34
【问题描述】:

所以,我有一个烧瓶视图,它将芹菜任务添加到队列中,并向用户返回 200。

from flask.views import MethodView
from app.tasks import launch_task

class ExampleView(MethodView):
    def post(self):
        # Does some verification of the incoming request, if all good:
        launch_task(task, arguments)
        return 'Accepted', 200

问题在于测试以下内容,我不想拥有 celery 实例等。我只想知道,在所有验证都正常之后,它会向用户返回 200。 celery launch_task() 将在别处进行测试。

因此,我热衷于模拟 launch_task() 调用,所以它基本上什么都不做,使我的单元测试独立于 celery 实例。

我尝试过以下各种化身:

@mock.patch('app.views.launch_task.delay'):
def test_launch_view(self, mock_launch_task):
    mock_launch_task.return_value = None
    # post a correct dictionary to the view
    correct_data = {'correct': 'params'}
    rs.self.app.post('/launch/', data=correct_data)
    self.assertEqual(rs.status_code, 200)

@mock.patch('app.views.launch_task'):
def test_launch_view(self, mock_launch_task):
    mock_launch_task.return_value = None
    # post a correct dictionary to the view
    correct_data = {'correct': 'params'}
    rs.self.app.post('/launch/', data=correct_data)
    self.assertEqual(rs.status_code, 200)

但似乎无法让它工作,我的视图只是以 500 错误退出。任何帮助将不胜感激!

【问题讨论】:

    标签: python unit-testing mocking flask celery


    【解决方案1】:

    我也尝试了任何 @patch 装饰器,但没有成功 我在setUp 中找到了 mock:

    import unittest
    from mock import patch
    from mock import MagicMock
    
    class TestLaunchTask(unittest.TestCase):
        def setUp(self):
            self.patcher_1 = patch('app.views.launch_task')
            mock_1 = self.patcher_1.start()
    
            launch_task = MagicMock()
            launch_task.as_string = MagicMock(return_value = 'test')
            mock_1.return_value = launch_task
    
        def tearDown(self):
            self.patcher_1.stop()
    

    【讨论】:

      【解决方案2】:

      @task 装饰器将函数替换为Task 对象(请参阅documentation)。如果您模拟任务本身,您将用MagicMock 替换(有点神奇)Task 对象,它根本不会安排任务。而是模拟 Task 对象的 run() 方法,如下所示:

      # With 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-14
        • 1970-01-01
        • 2012-08-18
        • 1970-01-01
        • 2014-04-14
        • 1970-01-01
        • 2013-11-26
        • 2013-08-15
        相关资源
        最近更新 更多