回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<h2>简言之</h2>
<p>在Flask SqlAlchemy中测试模型类时,如何模拟方法<code>.query.filter_by()</code>,以便返回模拟模型对象的列表?</p>
<h2>全部细节</h2>
<p>假设我们有一个如下代码所示的模型类</p>
<pre><code>from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class SomeModel(db.Model):
# more column mapping and methods go here
</code></pre>
<p>然后在我们的烧瓶代码中我们调用</p>
<pre><code>SomeModel.query.filter_by(...)
</code></pre>
<p>在我们的测试代码中,将<a href="https://docs.python.org/2/library/unittest.html" rel="noreferrer">Python unittest</a>模型与<a href="https://www.toptal.com/python/an-introduction-to-mocking-in-python" rel="noreferrer">mocking</a>一起使用,我们希望模拟<code>filter_by()</code>调用,以便它在我们设计的测试用例下返回模型对象列表。</p>
<p>我们怎么才能做到?</p>
<p>附则</p>
<p>我的google搜索只找到了<a href="https://stackoverflow.com/a/28194452/248616">this related post</a>;尽管在类的开头应用<code>@patch("flask_sqlalchemy.SignallingSession", autospec=True)</code>对我不起作用。</p>
<p>我还尝试将函数模拟为下面的代码片段</p>
<pre><code>@patch('app.model.some_model.SomeModel.query.filter_by')
def test_some_case(self, filterbyMOCK):
# more test logic goes here
</code></pre>
<p>启动时代码立即出错</p>
<pre><code>RuntimeError: application not registered on db instance and no application bound to current context
</code></pre>
<p>下面是来自PyCharm IDE的完整错误快照。</p>
<pre><code>Traceback (most recent call last):
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/mock/mock.py", line 1297, in patched
arg = patching.__enter__()
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/mock/mock.py", line 1353, in __enter__
self.target = self.getter()
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/mock/mock.py", line 1523, in <lambda>
getter = lambda: _importer(target)
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/mock/mock.py", line 1210, in _importer
thing = _dot_lookup(thing, comp, import_path)
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/mock/mock.py", line 1197, in _dot_lookup
return getattr(thing, comp)
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 428, in __get__
return type.query_class(mapper, session=self.sa.session())
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 78, in __call__
return self.registry()
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/sqlalchemy/util/_collections.py", line 990, in __call__
return self.registry.setdefault(key, self.createfunc())
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 136, in __init__
self.app = db.get_app()
File "/home/namgivu/NN/code/someproject-cloud/venv/local/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 809, in get_app
raise RuntimeError('application not registered on db '
RuntimeError: application not registered on db instance and no application bound to current context
</code></pre>