在Flask中测试经过身份验证的端点

时间:2014-10-23 02:42:39

标签: unit-testing authentication flask flask-login flask-restful

我有一个使用LDAP进行身份验证的Flask应用程序,其中有几个端点使用flask-restful进行管理,但是我希望单元测试经过身份验证的端点,而实际上不会访问LDAP服务器。我希望通过假装登录current_user来做到这一点,但我无法让这个技巧发挥作用。这是我尝试过的:

端点是经过身份验证的,因为我从我自己的类派生了所有资源(这在实践和手动测试中都很好用,并且是烧瓶式的建议):

def authenticate(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if not getattr(func, 'authenticated', True):
            return func(*args, **kwargs)
        if flask.ext.login.current_user and flask.ext.login.current_user.is_authenticated():
            return func(*args, **kwargs)
        flask.ext.restful.abort(401)
    return wrapper

class AuthenticatedResource(flask.ext.restful.Resource ):
    method_decorators = [authenticate]

这是一个简单的终点:

class RootResource(AuthenticatedResource):
    def get(self):
        return {'message':'Hello'}

现在在我的单元测试中,我认为我应该能够通过写入flask-login' current_user来模拟经过身份验证的用户:

from flask.ext.login import UserMixin, current_user

class AuthenticatedUser(UserMixin):
    def is_authenticated(self):
        return True
    def is_active(self):
        return True
    def is_anonymous(self):
        return False
    def get_id(self):
        return "Test User"

class TestMyAPI(unittest.TestCase):
    def test_root_endpoint_responds_properly(self):
        with app.test_client() as client:
            current_user = AuthenticatedUser()
            response = client.get('/')
            self.assertEqual(response.status_code, 200)
            body = json.loads(response.data)
            self.assertEqual(body, {'message':'Hello'})

不幸的是,测试失败了:

==================================================================
FAIL: test_root_endpoint_responds_properly (test_my_api.TestMyAPI)
------------------------------------------------------------------
Traceback (most recent call last):
  File "xxxx/test_graph_api.py", line xxx, in test_root_endpoint_responds_properly
    self.assertEqual(response.status_code, 200)
AssertionError: 401 != 200

其他说明:我使用的是烧瓶0.9,而不是0.10。我知道Miguel Grinberg's answer to a similar problem但我实际上并不想要登录;我想完全绕过LDAP(或任何测试数据库)的使用。

为什么current_user覆盖技巧不起作用?我应该使用其他方法吗?

1 个答案:

答案 0 :(得分:2)

问题中的代码不起作用的原因是该行

current_user = AuthenticatedUser()

创建一个名为current_user的新局部变量。这与flask.ext.login.current_user不同。

该行应更改为:

flask.ext.login.current_user = AuthenticatedUser()