วิธีส่งคำขอด้วย JSON ในการทดสอบหน่วย


101

ฉันมีรหัสภายในแอปพลิเคชัน Flask ที่ใช้ JSON ในคำขอและฉันสามารถรับวัตถุ JSON ได้ดังนี้:

Request = request.get_json()

สิ่งนี้ใช้งานได้ดี แต่ฉันพยายามสร้างการทดสอบหน่วยโดยใช้โมดูลที่ไม่เหมาะสมที่สุดของ Python และฉันมีปัญหาในการหาวิธีส่ง JSON พร้อมกับคำขอ

response=self.app.post('/test_function', 
                       data=json.dumps(dict(foo = 'bar')))

สิ่งนี้ทำให้ฉัน:

>>> request.get_data()
'{"foo": "bar"}'
>>> request.get_json()
None

ดูเหมือนว่า Flask จะมีอาร์กิวเมนต์ JSON ซึ่งคุณสามารถตั้งค่า json = dict (foo = 'bar') ในคำขอโพสต์ แต่ฉันไม่รู้ว่าจะทำอย่างไรกับโมดูลที่ไม่เหมาะสมที่สุด


อะไรrequest.dataมี? บ่อยครั้งที่การแยกวิเคราะห์ json ล้มเหลวเนื่องจากการป้อนข้อมูลที่ไม่ถูกต้องมันจะล้มเหลวโดยไม่โต้ตอบและส่งคืนNoneดังนั้นข้อมูลอินพุตดิบอาจไม่ใช่ json
Benoît Latinier

>>> request.get_data () '{"foo": "bar"}' >>> request.get_json () ไม่มีฉันไม่ค่อยแน่ใจว่าคำขอของขวดทำงานอย่างไร แต่ดูเหมือนว่าจะแยกข้อมูลกับ json และฉัน คิดไม่ออกว่าจะส่งข้อมูลไปยัง json ได้อย่างไรแทนที่จะเป็นข้อมูลหากเป็นเช่นนั้น
Sepehr Nazari

9
ฉันคิดว่าเป็นส่วนหัวของประเภทเนื้อหาลองตั้งค่าเป็น appliacation / json นอกจากนี้พารามิเตอร์แรงก็มีประโยชน์ แต่คุณอาจไม่ต้องการไปที่นั่นเพียงเพื่อให้ unittests ผ่านไปดีกว่าเพื่อเปลี่ยนละครใบ้
user3012759

คำตอบ:


201

เปลี่ยนโพสต์เป็น

response=self.app.post('/test_function', 
                       data=json.dumps(dict(foo='bar')),
                       content_type='application/json')

ซ่อมมัน.

ขอบคุณผู้ใช้ 3012759


กำลังทำลายหัวของฉันด้วยสิ่งนี้ ไม่เข้าใจว่าทำไมคุณต้องทิ้งข้อมูลเมื่อคุณระบุapplication/jsonประเภทเนื้อหาแล้ว
dimmg

ฉันเชื่อว่าเป็นเพราะทุกสิ่งที่คุณส่งในโพสต์จะต้องเป็นสตริง
Sepehr Nazari

18
สิ่งที่น่าทึ่งนี้ไม่ได้อยู่ในเอกสารเนื่องจาก test_client ของ flask ไม่มีเอกสาร API!
rjurney

จะรับข้อมูลจากการตอบกลับได้อย่างไร?
ตัวแปร

@variable กับการตอบสนองจากที่post ร้องขอเช่นคุณสามารถเข้าถึงข้อมูลเป็นไบต์ด้วยresp = client.post('/my/endpoint/',json=my_json_data) resp.data
amiabl

44

UPDATE:ตั้งแต่ขวด 1.0 เปิดflask.testing.FlaskClientวิธีการยอมรับjsonข้อโต้แย้งและResponse.get_jsonวิธีการเพิ่มดูตัวอย่าง

สำหรับ Flask 0.x คุณสามารถใช้ใบเสร็จด้านล่าง:

from flask import Flask, Response as BaseResponse, json
from flask.testing import FlaskClient
from werkzeug.utils import cached_property


class Response(BaseResponse):
    @cached_property
    def json(self):
        return json.loads(self.data)


class TestClient(FlaskClient):
    def open(self, *args, **kwargs):
        if 'json' in kwargs:
            kwargs['data'] = json.dumps(kwargs.pop('json'))
            kwargs['content_type'] = 'application/json'
        return super(TestClient, self).open(*args, **kwargs)


app = Flask(__name__)
app.response_class = Response
app.test_client_class = TestClient
app.testing = True

1
และอย่าลืมว่าอาร์กิวเมนต์ json ต้องเป็น dictไม่ใช่สตริง JSON!
LaundroMat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.