Cara mengirim permintaan dengan JSON dalam pengujian unit

96

Saya memiliki kode dalam aplikasi Flask yang menggunakan JSON dalam permintaannya, dan saya bisa mendapatkan objek JSON seperti ini:

Request = request.get_json()

Ini telah berfungsi dengan baik, namun saya mencoba membuat pengujian unit menggunakan modul unittest Python dan saya mengalami kesulitan menemukan cara untuk mengirim JSON dengan permintaan tersebut.

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

Ini memberi saya:

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

Flask tampaknya memiliki argumen JSON di mana Anda dapat menyetel json = dict (foo = 'bar') di dalam permintaan posting, tetapi saya tidak tahu bagaimana melakukannya dengan modul unittest.

Sepehr Nazari
sumber
Apa request.dataisinya? Seringkali ketika parsing json gagal karena input yang salah, gagal diam-diam dan kembali Nonesehingga data input mentah mungkin bukan json.
Benoît Latinier
>>> request.get_data () '{"foo": "bar"}' >>> request.get_json () Tidak ada Saya tidak begitu yakin bagaimana permintaan flask bekerja, tetapi tampaknya memisahkan data dan json, dan saya tidak tahu bagaimana mengirim informasi ke json daripada data, jika itu masuk akal.
Sepehr Nazari
9
saya pikir itu adalah header tipe konten, coba setel ke appliacation / json. juga parameter gaya sangat membantu tetapi Anda mungkin tidak ingin pergi ke sana hanya untuk membuat unittests berlalu, lebih baik ubah pantomim
user3012759

Jawaban:

194

Mengubah postingan menjadi

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

memperbaikinya.

Terima kasih kepada pengguna3012759.

Sepehr Nazari
sumber
sedang menghancurkan kepalaku dengan ini. Tidak mengerti mengapa Anda harus membuang data saat Anda sudah menentukan application/jsontipe konten.
redup
Saya percaya itu karena semua yang Anda kirim dalam sebuah posting harus berupa string.
Sepehr Nazari
17
Luar biasa, ini tidak ada di dokumen, karena test_client dari flask tidak memiliki dokumen API!
rjurney
Bagaimana cara mendapatkan data dari respon?
variabel
@variable, dengan respons dari post permintaan seperti resp = client.post('/my/endpoint/',json=my_json_data)Anda dapat mengakses data sebagai byte dengan resp.data.
ramah
44

UPDATE: Sejak Flask 1.0 dirilis, flask.testing.FlaskClientmetode menerima jsonargumen dan Response.get_jsonmetode yang ditambahkan, lihat contoh .

untuk Flask 0.x Anda dapat menggunakan tanda terima di bawah ini:

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
Victor Gavro
sumber
1
Dan jangan lupa bahwa argumen json haruslah dictbukan string JSON!
LaundroMat