python - 对 Flask 蓝图的测试给出了属性错误
问题描述
我正在使用 Python3.6 中的 unittest 为我的应用程序编写测试。我正在为此测试创建一个简单的 Flask 应用程序,我想用它来注册我定义的蓝图。我遇到的问题是当我尝试导入我的蓝图时:
File "/app/test/__init__.py", line 1, in <module>
from . import test_views
File "/app/test/test_views.py", line 50, in <module>
from api.metrics.views import stats
File "/app/api/metrics/__init__.py", line 1, in <module>
from .views import stats
File "/app/api/metrics/views.py", line 13, in <module>
def get_stats(client=None):
File "/testenv/lib/python3.6/site-packages/flask/blueprints.py", line 161, in decorator
endpoint = options.pop("endpoint", f.__name__)
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 584, in __getattr__
raise AttributeError(name)
AttributeError: __name__
错误出现在我在这段代码中调用@stats.route...的地方:
stats = Blueprint('metrics', __name__)
@stats.route('/metrics', methods=['POST'])
@setup.require_suth
def get_metrics(client=None):
<This code is not relevant>
有谁知道如何正确地做到这一点?我真的不知道该怎么做。
这是我的结构:
/app
/api
/metrics
__init__.py
views.py
/test
test_views.py
这是我的测试中的导入语句:
app_ = define_test_app()
from api.metrics.views import stats
app_.register_blueprint(stats)
将不胜感激,因为我完全被困在这一点上。
解决方案
不要使用相同的名称命名模块、目录和蓝图。
基本上我们的代码有这种结构。子树使其更简单。
-- webcompat
|-- __init__.py
|-- form.py
|-- api
| |-- __init__.py
| |-- uploads.py
| |-- endpoints.py
…
|-- helpers.py
|-- views.py
所以在webcompat/__init__.py
from webcompat.api.endpoints import api
app = Flask(__name__, static_url_path='')
app.register_blueprint(api)
并且在webcompat/api/endpoints/__init__.py
from webcompat.helpers import cool_feature
api = Blueprint('api', __name__, url_prefix='/api')
@api.route('blah')
def somewhere(foo):
"""blablah"""
yeah = cool_feature()
那么这里发生了什么?模块和蓝图共享相同的名称。所以如果在测试中我们需要模拟cool_feature:
with patch('webcompat.api.endpoints.cool_feature') as mock_cool:
我们需要记住,在模拟时,我们不会模拟已定义的功能(aka webcompat.helpers.cool_feature
),而是已导入的功能(aka webcompat.api.endpoints.cool_feature
)。在这种情况下我们将无法模拟,因为会有名称冲突。错误将是:
E AttributeError: 'Blueprint' object has no attribute 'endpoints'
因为命名webcompat.api
蓝图没有属性endpoints
,而模块webcompat.api
有属性。
推荐阅读
- apache - 重写 url - apache - htaccess
- django - 运行配置错误:请在 PyCharm 中指定脚本名称
- jpa - @Stateless 和 @Asynchronous EJB 之间的 JPA 事务处理
- html - 更改响应背景颜色的文本颜色
- python - Pandas 数据框获取列名和 value_counts
- python - 将 Pandas 数据框转换为字典
- scala - Spark scala 更快的 groupbykey 和排序 rdd 值的方法
- python - Python 计算来自两个 int 数组的事件发生次数
- r - 在R中将基于年份的向量与基于年份和月份的矩阵相乘
- java - 如何给某个键盘命令让我们说 10-20 个标签 Tabs ,