<p>您必须模拟整个映射器类;访问映射器上的<code>query</code>属性将导致会话加载:</p>
<pre><code>@patch('app.model.some_model.SomeModel')
def test_some_case(self, some_model_mock):
filter_by_mock = some_model_mock.query.filter_by
# more test logic goes here
</code></pre>
<p>这是因为<code>.query</code>属性是一个描述符对象;访问它会触发对会话的绑定。</p>
<p>另一种方法是模拟<a href="https://github.com/mitsuhiko/flask-sqlalchemy/blob/f4662ad464a73befa47cf74754fdbfe156570e59/flask_sqlalchemy/__init__.py#L494-L500" rel="noreferrer">^{<cd3>} method</a>(它支持<code>.query</code>属性);仅当<em>必须用实际的<code>SomeModel</code>实例进行</em>测试时才使用此方法:</p>
<pre><code>@patch('flask_sqlalchemy._QueryProperty.__get__')
def test_some_case(self, query_property_getter_mock):
filter_by_mock = query_property_getter_mock.return_value.filter_by
# more test logic goes here
</code></pre>
<p>演示:</p>
<pre><code>>>> from flask_sqlalchemy import SQLAlchemy
>>> db = SQLAlchemy()
>>> class SomeModel(db.Model):
... id = db.Column(db.Integer, primary_key=True)
...
>>> from unittest import mock
>>> with mock.patch('__main__.SomeModel') as model_mock:
... filter_by = model_mock.query.filter_by
... SomeModel.query.filter_by(SomeModel.id == 'foo')
...
<MagicMock name='SomeModel.query.filter_by()' id='4438980312'>
>>> with mock.patch('flask_sqlalchemy._QueryProperty.__get__') as query_property_getter_mock:
... filter_by_mock = query_property_getter_mock.return_value.filter_by
... SomeModel.query.filter_by(SomeModel.id == 'foo')
...
<MagicMock name='__get__().filter_by()' id='4439035184'>
</code></pre>