从Mock 3.0.5升级到4.0.0后,我的单元测试失败。我猜测patch
不再适用于flask.g
,但我找不到解决方法。
from mock import patch
import flask
def some_function():
flask.g.somevariable = True
return flask.g.somevariable
@patch('flask.g')
def test_some_function(mock_flask_global):
assert some_function()
输出:
name = 'g'
def _lookup_app_object(name):
top = _app_ctx_stack.top
if top is None:
> raise RuntimeError(_app_ctx_err_msg)
E RuntimeError: Working outside of application context.
E
E This typically means that you attempted to use functionality that needed
E to interface with the current application object in some way. To solve
E this, set up an application context with app.app_context(). See the
E documentation for more information.
venv/lib/python3.6/site-packages/flask/globals.py:45: RuntimeError
========================================================================================================== short test summary info ===========================================================================================================
FAILED temp_test.py::test_some_function - RuntimeError: Working outside of application context.
这在模拟3.0.5中正常工作
python开发人员或flask开发人员都不认为这是一个错误。 从python 3.8开始,带有unittest.mock和模拟版本4.0.0(它们相同),它将检查要打补丁的属性是否首先存在。应该返回属性或引发AttributeError。 Flask引发RuntimeError,从而破坏了预期的逻辑。另外,Flask开发人员建议根本不修补flask.g,因为它只是flask.globals的代理。
最终,我将数据库连接存储在flask.g.db中,并希望对此进行修补。我的解决方案是在构建时将数据库连接传递到资源中,并且在我的before_request和teardown_request调用之外不使用flask.g。在某些情况下,我确实需要对其进行修补,我只需要正确设置应用程序上下文即可。