簡體   English   中英

在本地測試 (Python) Google Cloud Function 時出現應用程序上下文錯誤

[英]Application context errors when locally testing a (Python) Google Cloud Function

我正在嘗試在本地測試我希望部署為 Google Cloud Function 的 Python 函數。 這些函數似乎本質上是基於 Flask 的,而且我發現返回 JSON 的最佳方式是使用 Flask 的 jsonify 函數。 這在部署時似乎工作正常,但我想設置一些本地單元測試,這就是我卡住的地方。 簡單地添加行以導入 jsonify,會導致以下錯誤:

RuntimeError: Working outside of application context.

Stackoverflow 上有幾篇文章似乎與此問題相關,但 Google Cloud Functions 並未真正遵循 Flask 模式。 據我所知,沒有應用上下文,也沒有裝飾器。 我發現的所有示例對這個特定用例都沒有用處。 任何人都可以建議一種構建單元測試的方法,該方法將尊重應用程序上下文並且仍然與此處的 GCF 模式保持一致。

我有一個單元測試,我可以分享它,但是當你運行以下命令時,你會看到同樣的錯誤,在main中調用方法。

import os
import json
from flask import jsonify
from unittest.mock import Mock

def dummy_request(request):

    request_json = request.get_json()
    if request_json and 'document' in request_json:
        document = request_json['document']
    else:
        raise ValueError("JSON is invalid, or missing a 'docuemnt' property")

    data = document
    return jsonify(data)


if __name__ == '__main__':
    data = {"document":"This is a test document"}
    request = Mock(get_json=Mock(return_value=data), args=data)
    result = dummy_request(request)
    print(result)

您真的不需要測試flask.jsonify是否按預期工作,對嗎? 這是一個第三方功能。

您實際上要測試的是flask.jsonify是使用正確的數據調用的,因此您可以只修補flask.jsonify ,並對是否調用模擬進行斷言:

import flask
from unittest.mock import Mock, patch

def dummy_request(request):

    request_json = request.get_json()
    if request_json and 'document' in request_json:
        document = request_json['document']
    else:
        raise ValueError("JSON is invalid, or missing a 'docuemnt' property")

    data = document
    return flask.jsonify(data)


@patch('flask.jsonify')
def test(mock_jsonify):
    data = {"document": "This is a test document"}
    request = Mock(get_json=Mock(return_value=data), args=data)
    dummy_request(request)
    mock_jsonify.assert_called_once_with("This is a test document")


if __name__ == '__main__':
    test()

我建議您查看有關如何測試 Flask 應用程序的 Flask 文檔,它很好地描述了如何設置測試和獲取應用程序上下文。

PS jsonify需要應用程序上下文,但json.dumps不需要。 也許你可以使用后者?

我遇到了同樣的問題。 正如您所說,燒瓶測試似乎不太適合 Cloud Functions,我對代碼的工作方式很滿意,所以不想改變它。 在測試的 setUp() 中添加應用程序上下文,然后將其用於所需的調用對我有用。 像這樣的東西......

import unittest
import main
from flask import Flask

class TestSomething(unittest.TestCase):

    def setUp(self):
        self.app = Flask(__name__)

    def test_something(self):      

        with self.app.app_context():
            (body, code) = main.request_something()

        self.assertEqual(200, code, "The request did not return a successful response")

    if __name__ == '__main__':
        unittest.main()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM