Does anyone know of a way to set (mock) the User-Agent of the request object provided by FLask (Werkzeug) during unit testing?
As it currently stands, when I attempt to obtain details such as the request.headers['User-Agent'] a KeyError is raised as the Flask test_client() doesn't set these up. (See partial stack trace below)
When attempting to get the User-Agent from the request object in a Flask project during unit testing, a KeyError is raised.
File "/Users/me/app/rest/app.py", line 515, in login if request.headers['User-Agent']: File "/Users/me/.virtualenvs/app/lib/python2.7/site-packages/werkzeug/datastructures.py", line 1229, in __getitem__ return self.environ['HTTP_' + key] KeyError: 'HTTP_USER_AGENT'
-- UPDATE --
Along with the (accepted) solution below, the environ_base hint lead me to this other SO solution. The premise of this solution is to create a wrapper class for the Flask app and override the call method to automatically set the environment variables. This way, the variables are set for all calls. So, the solution I ended up implementing is creating this proxy class:
class FlaskTestClientProxy(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): environ['REMOTE_ADDR'] = environ.get('REMOTE_ADDR', '127.0.0.1') environ['HTTP_USER_AGENT'] = environ.get('HTTP_USER_AGENT', 'Chrome') return self.app(environ, start_response)
And then wrapping the WSGI container with that proxy:
app.wsgi_app = FlaskTestClientProxy(app.wsgi_app) test_client = app.test_client()
You need to pass in environ_base
when you call get()
or post()
. E.g.,
client = app.test_client() response = client.get('/your/url/', environ_base={'HTTP_USER_AGENT': 'Chrome, etc'})
Then your request.user_agent
should be whatever you pass in, and you can access it via request.headers['User-Agent']
.
See http://werkzeug.pocoo.org/docs/test/#testing-api for more info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With