2017-02-13 1 views
1

Comment une unité peut-elle tester un point de terminaison API REST écrit dans flask qui accepte un objet dictionnaire imbriqué pour le corps de la requête?Tests unitaires avec objets imbriqués dans la demande à l'aide de la fiole

Voici un exemple en utilisant flacon et webargs pour la validation d'entrée,

from flask import Flask 
from webargs import fields 
from webargs.flaskparser import use_args 

app = Flask(__name__) 

hello_args = { 
    'a': fields.Nested({'name' : fields.Str()}) 
} 

@app.route('/', methods=['POST']) 
@use_args(hello_args) 
def index(args): 
    return 'Hello ' + str(args) 


def test_app(): 
    app.config['TESTING'] = True 
    test_app = app.test_client(use_cookies=False) 
    test_app.post(data={"a": {"name": "Alice"}}) 


if __name__ == '__main__': 
    app.run() 

qui fonctionne correctement lorsque vous utilisez ce enpoint directement,

% curl -H "Content-Type: application/json" -X POST \ 
     -d '{"a":{"name": "Alice"}}' http://localhost:5000 

Hello {'a': {'name': 'Alice'}}% 

soulève cependant une exception dans werkzeug.test.EnvironBuilder quand il est appelé à l'intérieur tests unitaires,

nosetests /tmp/test.py              
E 
====================================================================== 
ERROR: test.test_app 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/lib64/python3.4/site-packages/nose/case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "/tmp/test.py", line 26, in test_app 
    test_app.post(data={"a": {"name": "Alice"}}) 
    File "/home/rth/.local/lib64/python3.4/site-packages/werkzeug/test.py", line 788, in post 
    return self.open(*args, **kw) 
    File "/home/rth/.local/lib64/python3.4/site-packages/flask/testing.py", line 103, in open 
    builder = make_test_environ_builder(self.application, *args, **kwargs) 
    File "/home/rth/.local/lib64/python3.4/site-packages/flask/testing.py", line 34, in make_test_environ_builder 
    return EnvironBuilder(path, base_url, *args, **kwargs) 
    File "/home/rth/.local/lib64/python3.4/site-packages/werkzeug/test.py", line 338, in __init__ 
    self._add_file_from_data(key, value) 
    File "/home/rth/.local/lib64/python3.4/site-packages/werkzeug/test.py", line 355, in _add_file_from_data 
    self.files.add_file(key, **value) 
TypeError: add_file() got multiple values for argument 'name' 

---------------------------------------------------------------------- 
Ran 1 test in 0.011s 

FAILED (errors=1) 

cela utilise Pytho n 3.5, flacon 0.12 et webargs 1.5.2.

a également présenté une question à https://github.com/pallets/flask/issues/2176

Répondre

0

Il semble que, malgré l'utilisation de webargs, les données d'entrée doivent encore être sérialisés et content_type explicitement spécifié pour le cela fonctionne. En particulier, le remplacement

test_app.post(data={"a": {"name": "Alice"}}) 

avec

test_app.post(data=json.dumps({"a": {"name": "Alice"}}), 
      content_type='application/json') 

fixé à ce problème (voir également lié réponses pour here).