如何 pass/mock gae 中的 admin_required 装饰器?

How to pass/mock the admin_required decorator in gae?

class Generator(Resource):

    @admin_required
    def get(self):
       pass

如果我在我的视图上添加 @admin_required 装饰器,单元测试开始失败,并显示消息:

RuntimeError: working outside of request context

有没有办法模拟它或绕过它进行单元测试?

这是装饰器:

def admin_required(func):
    """Requires App Engine admin credentials"""
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if users.get_current_user():
            if not users.is_current_user_admin():
                abort(401)  # Unauthorized
            return func(*args, **kwargs)
        return redirect(users.create_login_url(request.url))
    return decorated_view

我只修补用户模块:

from google.appengine.api import users

# ...

@mock.patch.object(users, 'get_current_user')
@mock.patch.object(users, 'is_current_user_admin', return_value=True)
def test_handler(mock_get_current_user, mock_is_current_user_admin):
    invoke_your_handler()
    # make assertions, etc.

如果你想更深入,你可以使用那个 GAE 测试平台......不幸的是,这里的文档似乎很差而且很难正确......基于 this answer,它看起来像你需要创建一个testbed实例然后设置环境:

from google.appengine.ext import testbed

testbed = testbed.TestBed()
testbed.activate()
testbed.init_user_stub()
# Sets environment variables...
testbed.setup_env(
    user_email='hello@gmail.com',
    user_id='123456',
    user_is_admin='1',  # '1' is an admin, '0' is a non-admin.
    overwrite=True,
)

现在照常继续测试。如果您使用 unittest 进行测试,您可能希望将所有这些有趣的东西打包到您的 setUp 方法中。

另请注意,为了避免污染您的环境,您需要在测试结束时调用 testbed.deactivate()