【问题标题】:Is there a way to mock flask request object inside a function?有没有办法在函数中模拟烧瓶请求对象?
【发布时间】:2021-01-18 21:56:02
【问题描述】:

我需要测试一个方法的响应,这个方法调用了 2 个不同的方法。该方法的响应是针对这两个内部方法创建的。内部方法的 1 使用烧瓶请求对象作为其实现中的输入。

代码示例更好地解释了它:

class ApiDetail():

    def process_data(self, process_input):
        try:
            request_simple_url = self.handle_url(request.base_url, request.view_args)
            return self.validate_input(request_simple_url, process_input)
        except NotFoundException as e:
            return {"error": str(e)}, HTTPStatus.UNAUTHORIZED
        #implementation detail


    @staticmethod
    def handle_url(request_base_url, request_arguments):
        #implementation detail


def test_process_data():
    with mock.patch('ApiDetail.validate_input', return_value = NotFoundException):
        with mock.patch('ApiDetail.handle_url', return_value='test_handled'):
            assert ApiDetail.process_data(self=ApiDetail, process_input='test_input') == NotFoundException

我正在尝试测试 process_data 方法。如果 validate_input 方法出现异常,我断言 process_data 也会返回异常。这行有问题,我无法模拟 request 对象,因为它不是 process_data 方法的输入:

request_simple_url = self.handle_url(request.base_url, request.view_args)

错误信息很清楚,但我找不到方法:

name = 'request'

def _lookup_req_object(name):
    top = _request_ctx_stack.top
    if top is None:
        raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context. This typically means that you attempted
to use functionality that needed an active HTTP request.      
Consult the documentation on testing for information about how to avoid this problem.

如果handle_url在没有任何输入值的情况下实现,它会正常工作,但需要从方法外接收请求对象属性。

有什么办法可以解决这个问题吗?

【问题讨论】:

  • 您可以编辑以显示您遇到的错误吗?我不确定我是否完全理解你在问什么
  • 我添加了错误信息,很清楚但还是找不到路。

标签: python flask pytest python-unittest python-mock


【解决方案1】:

您可以在 process_data 方法之外使用您的全局请求对象,并将其属性传递给您的方法:

class ApiDetail():

    base_url = request.base_url
    view_args = request.view_args

    def process_data(self, process_input, base_url, view_args):
        try:
            request_simple_url = self.handle_url(base_url, view_args)
            return self.validate_input(request_simple_url, process_input)
        except NotFoundException as e:
            return {"error": str(e)}, HTTPStatus.UNAUTHORIZED
        #implementation detail

    @staticmethod
    def handle_url(request_base_url, request_arguments):
        #implementation detail


def test_process_data():
    with mock.patch('ApiDetail.validate_input', return_value = NotFoundException):
        with mock.patch('ApiDetail.handle_url', return_value='test_handled'):
            assert ApiDetail.process_data(self=ApiDetail, process_input='test_input', base_url='test_url', view_args='test_args') == NotFoundException

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 2019-11-11
    • 2014-07-23
    • 2016-10-23
    • 1970-01-01
    • 2020-03-10
    相关资源
    最近更新 更多