2013-05-07 8 views
5

Ich verwende Flask und habe Endpunkte, die eine Autorisierung erfordern (und gelegentlich andere App-spezifische Header). In meinen Tests verwenden Sie die test_client-Funktion, um einen Client zu erstellen und dann die verschiedenen Aufrufe von get, put, delete auszuführen. Alle diese Anrufe erfordern eine Autorisierung und weitere Header müssen hinzugefügt werden. Wie kann ich den Testclient einrichten, um solche Header auf alle Anfragen zu setzen?HTTP-Header für alle Anfragen in einem Flask-Test setzen

Antwort

11

Sie können die WSGI App wickeln und Header dort injizieren:

from flask import Flask, request 
import unittest 

def create_app(): 
    app = Flask(__name__) 

    @app.route('/') 
    def index(): 
     return request.headers.get('Custom', '') 

    return app 

class TestAppWrapper(object): 

    def __init__(self, app): 
     self.app = app 

    def __call__(self, environ, start_response): 
     environ['HTTP_CUSTOM'] = 'Foo' 
     return self.app(environ, start_response) 


class Test(unittest.TestCase): 

    def setUp(self): 
     self.app = create_app() 
     self.app.wsgi_app = TestAppWrapper(self.app.wsgi_app) 
     self.client = self.app.test_client() 

    def test_header(self): 
     resp = self.client.get('/') 
     self.assertEqual('Foo', resp.data) 


if __name__ == '__main__': 
    unittest.main() 
9

Die Client Klasse nimmt die gleichen Argumente wie die EnvironBuilder Klasse, darunter die headers Schlüsselwort-Argument.

So können Sie einfach client.get('/', headers={ ... }) verwenden, um Ihre Authentifizierung zu senden.

Nun, wenn Sie einen Standardsatz von Header aus dem Client zur Verfügung zu stellen mögen, müssen Sie Ihre eigene Implementierung von open zu schaffen, die einen modifizierte Umgebung Builder (ähnlich make_test_environ_builder) liefert und setzten app.test_client_class auf Ihren Punkt neue Klasse.

2

Aufbauend auf @DazWorrall Antwort, und Blick in die Werkzeug-Quellcode, ich mit dem folgenden Wrapper für die Weitergabe Standard Headers gelandet, die ich für die Authentifizierung benötigt:

class TestAppWrapper: 
    """ This lets the user define custom defaults for the test client. 
    """ 

    def build_header_dict(self): 
     """ Inspired from : https://github.com/pallets/werkzeug/blob/master/werkzeug/test.py#L591 """ 
     header_dict = {} 
     for key, value in self._default_headers.items(): 
      new_key = 'HTTP_%s' % key.upper().replace('-', '_') 
      header_dict[new_key] = value 
     return header_dict 

    def __init__(self, app, default_headers={}): 
     self.app = app 
     self._default_headers = default_headers 

    def __call__(self, environ, start_response): 
     new_environ = self.build_header_dict() 
     new_environ.update(environ) 
     return self.app(new_environ, start_response) 

Sie können dann verwenden Sie es mögen:

class BaseControllerTest(unittest.TestCase): 

    def setUp(self): 
     _, headers = self.get_user_and_auth_headers() # Something like: {'Authorization': 'Bearer eyJhbGciOiJ...'} 
     app.wsgi_app = TestAppWrapper(app.wsgi_app, headers) 
     self.app = app.test_client() 

    def test_some_request(self): 
     response = self.app.get("/some_endpoint_that_needs_authentication_header") 
0

Sie können Header innerhalb Testclient festlegen.

client = app.test_client() 
client.environ_base['HTTP_AUTHORIZATION'] = 'Bearer your_token' 

Dann können Sie Header aus Anfrage verwenden:

request.headers['Authorization'] 
Verwandte Themen