1
class Generator(Resource):

    @admin_required
    def get(self):
       pass

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

RuntimeError:在请求上下文之外工作

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

这是装饰器:

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
4

1 回答 1

3

我只是修补用户模块:

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 测试台......不幸的是,这里的文档似乎很差而且很难正确......根据这个答案,看起来你需要创建一个测试台实例和然后设置环境:

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()在测试结束时调用。

于 2015-02-03T00:29:49.327 回答