我正在尝试使用 Flask-Testing 测试 Flask-SQLAlchemy 模型。更准确地说,该模型的静态方法使用了 first_or_404()
,但我找不到使我的测试工作的方法。
这里有一个突出问题的自包含示例:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask.ext.testing import TestCase
db = SQLAlchemy()
class ModelToTest(db.Model):
__tablename__ = 'model_to_test'
identifier = db.Column(db.String(80), unique=True, nullable=False, primary_key=True)
@staticmethod
def get_by_identifier(identifier):
return ModelToTest.query.filter_by(identifier=identifier).first_or_404()
class Config:
DEBUG = True
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///'
SQLALCHEMY_TRACK_MODIFICATIONS = False
class TestGetByIdentifier(TestCase):
def create_app(self):
app = Flask('test')
app.config.from_object(Config())
db.init_app(app)
return app
def setUp(self):
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
def test_get_by_identifier(self):
self.assert404(ModelToTest.get_by_identifier('identifier'))
我得到了错误:
(my_env) PS C:\Dev\Test\Python\test_flask> nosetests-3.4.exe
E
======================================================================
ERROR: test_get_by_identifier (test_flask.TestGetByIdentifier)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Dev\Test\Python\test_flask\test_flask.py", line 37, in test_get_by_identifier
self.assert404(ModelToTest.get_by_identifier('identifier'))
File "C:\Dev\Test\Python\test_flask\test_flask.py", line 13, in get_by_identifier
return ModelToTest.query.filter_by(identifier=identifier).first_or_404()
File "c:\\my_env\lib\site-packages\flask_sqlalchemy\__init__.py", line 431, in first_or_404
abort(404)
File "c:\\my_env\lib\site-packages\werkzeug\exceptions.py", line 646, in __call__
raise self.mapping[code](*args, **kwargs)
werkzeug.exceptions.NotFound: 404: Not Found
----------------------------------------------------------------------
Ran 1 test in 0.913s
所以行 self.assert404(ModelToTest.get_by_identifier('identifier'))
确实在 first_or_404()
调用中产生了一个异常,这个异常是一个 werkzeug.exceptions.NotFound
,这似乎不是 self.assert404()
所期望的。
运行此测试的要求是:
- flask
- flask -sqlalchemy
- flask 测试
值得注意的是,当我在应用程序中使用该函数时,它的行为符合预期。
提前致谢。
最佳答案
我引用了我在 GitHub 上收到的答案:
https://github.com/jarus/flask-testing/issues/89
I believe this is a misunderstanding about the way to drive the test. The
first_or_404
function will indeed raise aNotFound
exception. When in the context of the request, the exception will bubble up, be handled, and turn into a 404 http response, which is what flask-testing is looking for.However, you are not in the context of a request in this case since you are calling the method directly and it is simply resulting in an exception. You could do this to make the test work
from werkzeug.exceptions import NotFound def test_get_by_identifier(self): with self.assertRaises(NotFound): ModelToTest.get_by_identifier('identifier')
Or, you can stick that function behind a route and test it using self.client which will correctly give you a 404 http response. However, testing the exception (without the use of flask-testing) may be more appropriate in this case given the level you are testing at.
关于python - Flask-Testing 和 Flask-SQLAlchemy : first_or_404(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36816668/