简体   繁体   中英

Flask.test_client().post and JSON encoding

I am writing test cases for JSON endpoints in a Flask app.

import unittest
from flask import json
from app import create_app


class TestFooBar(unittest.TestCase):
    def setUp(self):
        self.app = create_app('testing')
        self.app_context = self.app.app_context()
        self.app_context.push()

    def test_ham(self):
        resp = self.client.post('/endpoint',
                                headers={'Content-Type': 'application/json'},
                                data=json.dumps({'foo': 2,
                                                 'bar': 3}))
        assert resp.status_code == 200

    def test_eggs(self):
        resp = self.client.post('/endpoint', data={'foo': 5,
                                                   'bar': 7})
        assert resp.status_code == 200

    def test_ham_and_eggs(self):
        with self.app.test_client() as self.client:
            self.test_ham()
            self.test_eggs()

Just to understand what's happening, do both ways of sending a POST message in the code above make sense? In particular, am I double-JSON encoding in the first case?

Or, briefly, what is the difference between test_ham and test_eggs ? Is there any?

You are not double-encoding JSON, no, because data doesn't encode anything to JSON. test_ham posts JSON, test_eggs does not.

Starting from Flask 1.0, the Flask test client supports posting JSON directly, via the json keyword argument, use it to cut down on boilerplate code here:

def test_ham(self):
    resp = self.client.post('/endpoint', json={'foo': 2, 'bar': 3})
    assert resp.status_code == 200

See the Testing JSON APIs section of the Flask Testing documentation chapter:

Passing the json argument in the test client methods sets the request data to the JSON-serialized object and sets the content type to application/json .

Passing a dictionary to data produces a different kind of request, a application/x-www-form-urlencoded encoded request just like a <form method="POST" ...> form would produce from your browser, and the foo and bar values would have to be accessed via the request.form object . Do not use it when posting JSON is needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM