Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
469 views
in Technique[技术] by (71.8m points)

python - Setting (mocking) request headers for Flask app unit test

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()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...