flask.request mocker.patch.object无效

时间:2019-09-16 13:01:18

标签: python unit-testing flask mocking pytest

在我的控制器中,我得到了这个端点:

let redis = require("redis");

var redisclient = redis.createClient({
  host: "localhost",
  port: 6379
});

redisclient.on("connect", function () {
  console.log("Redis Connected");
});

redisclient.on('ready', function () {
  console.log("Redis Ready");
});

redisclient.set("framework", "AngularJS", function (err, reply) {
  console.log("Redis Set" , reply);
});

redisclient.get("framework", function (err, reply) {
  console.log("Redis Get", reply);
});

redisclient.del("framework",function (err, reply) {
  console.log("Redis Del", reply);
});

然后,我尝试使用@bp_crawler.route('/insert', methods=['POST']) def insert_data(): req = requests.CrawledSocialDataRequest.from_json(json.loads(request.data)) pytest来测试pytest-mock固定装置。

我继续模拟mocker对象,以便request返回一些对我的单元测试有用的值。

request.data

一切都很好,除非调用# arrange data_to_insert = requests.CrawledSocialDataRequest([ requests.CrawledSocialDataRecord('cid0', 'content0', 123.4, ['tag0', 'tag1']), requests.CrawledSocialDataRecord('cid1', 'content1', 123.4, ['tag1', 'tag2']) ]) request_mock = mocker.patch.object(flask, 'request') request_mock.data = data_to_insert.serialize() db_mock = request_mock = mocker.patch.object(api, 'db') # act result = controller.insert_data()

我收到以下异常:

insert_data()

controllers/v1/tests/test_crawler.py:30: 

name ='request'

controllers/v1/crawler.py:36: in insert_data
    req = requests.CrawledSocialDataRequest.from_json(json.loads(request.data))
/usr/local/lib/python3.7/site-packages/werkzeug/local.py:347: in __getattr__
    return getattr(self._get_current_object(), name)
/usr/local/lib/python3.7/site-packages/werkzeug/local.py:306: in _get_current_object
    return self.__local()
def _lookup_req_object(name):
    top = _request_ctx_stack.top
    if top is None:
     

E RuntimeError:在请求上下文之外工作。   E
  E这通常意味着您尝试使用所需的功能   E一个活动的HTTP请求。查阅有关测试的文档   有关如何避免此问题的信息。

模拟未发生,因此request.data将控制权路由到 raise RuntimeError(_request_ctx_err_msg) ,导致我的单元测试失败。

Github链接: -Controller -Test

2 个答案:

答案 0 :(得分:1)

事实证明,如果在_test.py上,您将执行以下操作:

import flask
...
request_mock = mocker.patch.object(flask, 'request')

但是在您的控制器/端点上,您可以

from flask import request
...
x = request.data # this will break

因此,您必须执行import flask -> x = flask.request.data才能使其正常工作,或更改模拟技术。

答案 1 :(得分:-1)

您可以模拟来自控制器而非烧瓶的请求,例如:

request_mock = mocker.patch('controllers.v1.crawler.request')
request_mock.data = data_to_insert.serialize()