在after_request失败时,FlaskClient从g中设置cookie

时间:2015-03-09 13:11:32

标签: python cookies flask

在我的烧瓶测试客户端设置cookie时遇到问题。 使用FlaskFoundation样板+ Flask-BabelEx,在我为语言选择添加它们之后(在main.py中):

@main.before_request
def detect_user_language():
    language = request.cookies.get('user_lang') or\
        request.accept_languages.best_match(LANG_CHOICES)
    g.language = language


@main.after_request
def set_language_cookie(response):
    response.set_cookie('user_lang', value=g.language)
    return response


@main.route("/lang/<language_code>")
def switch_language(language_code):
    if language_code in LANG_CHOICES:
        g.language = language_code
    return redirect(url_for('main.home'))

之前的精确测试:

class TestForm:
    def setup(self):
        app = create_app('appname.settings.DevConfig', env='dev')
        self.app = app.test_client()
        db.app = app
        db.create_all()
        admin = User('admin', 'supersafepassword')
        db.session.add(admin)
        db.session.commit()

    def teardown(self):
        db.session.remove()
        db.drop_all()


    def test_user_login(self):
        rv = self.app.post('/login', data=dict(
            username='admin',
            password="supersafepassword"
        ), follow_redirects=True)

        assert rv.status_code == 200
        assert 'Logged in successfully.' in rv.data

因TypeError而失败:

self = <tests.test_login.TestForm instance at 0x415f328c>

    def test_user_login(self):
        rv = self.app.post('/login', data=dict(
            username='admin',
            password="supersafepassword"
>       ), follow_redirects=True)

tests/test_login.py:25: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/local/lib/python2.7/site-packages/werkzeug/test.py:784: in post
    return self.open(*args, **kw)
env/local/lib/python2.7/site-packages/flask/testing.py:108: in open
    follow_redirects=follow_redirects)
env/local/lib/python2.7/site-packages/werkzeug/test.py:742: in open
    response = self.run_wsgi_app(environ, buffered=buffered)
env/local/lib/python2.7/site-packages/werkzeug/test.py:659: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
env/local/lib/python2.7/site-packages/werkzeug/test.py:867: in run_wsgi_app
    app_iter = app(environ, start_response)
env/local/lib/python2.7/site-packages/flask/app.py:1836: in __call__
    return self.wsgi_app(environ, start_response)
env/local/lib/python2.7/site-packages/flask/app.py:1820: in wsgi_app
    response = self.make_response(self.handle_exception(e))
env/local/lib/python2.7/site-packages/flask/app.py:1403: in handle_exception
    reraise(exc_type, exc_value, tb)
env/local/lib/python2.7/site-packages/flask/app.py:1817: in wsgi_app
    response = self.full_dispatch_request()
env/local/lib/python2.7/site-packages/flask/app.py:1479: in full_dispatch_request
    response = self.process_response(response)
env/local/lib/python2.7/site-packages/flask/app.py:1691: in process_response
    response = handler(response)
appname/controllers/main.py:22: in set_language_cookie
    response.set_cookie('user_lang', value=g.language)
env/local/lib/python2.7/site-packages/werkzeug/wrappers.py:1008: in set_cookie
    self.charset))
env/local/lib/python2.7/site-packages/werkzeug/http.py:933: in dump_cookie
    buf = [key + b'=' + _cookie_quote(value)]
env/local/lib/python2.7/site-packages/werkzeug/_internal.py:223: in _cookie_quote
    for char in iter_bytes(b):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

x = None

>   iter_bytes = lambda x: iter(x)
E   TypeError: 'NoneType' object is not iterable

与其他请求测试一样。

1 个答案:

答案 0 :(得分:0)

Accept.best_match() method如果找不到匹配项,则返回None作为默认值。

您没有在请求中设置Accept-LanguageCookie标头,因此找不到匹配项,并且会为该语言返回None

然后设置g.language = None,然后尝试将其用作response.set_cookie()调用的值,该调用失败。

如果未找到匹配项,您可以指定要使用的默认值:

language = (
    request.cookies.get('user_lang') or
    # default language is English
    request.accept_languages.best_match(LANG_CHOICES, default='en'))