[英]Unit testing for ClassMethod of a model in Flask
我有两个数据库:一个是master
和用于测试,我有另一个数据库master_test
为了从表中检索总价,我在模型中创建了一个@classmethod
。 这种方法可以帮助我获得按月和年过滤的价格总和。 这是类方法:
@classmethod
def get_total_book_price(cls, id):
query = Book.query.with_entities(
func.sum(Book.price).label("price")
).filter(
extract('year', Book.created_at) >= datetime.date.today().year,
extract('month', Book.created_at) >= datetime.date.today().month
).filter(
Book.id == id
).all()
return query[0].price
这个查询很好用。 但是当我为测试用例运行它时,它显示的master
数据库不存在。 它应该找到master_test
数据库而不是master
数据库。 下面是测试代码:
def test_get_total_book_price(self):
id = 1
response = Book.get_total_book_price(id)
if not response:
self.assertEqual(response, False)
self.assertEqual(response, True)
它显示错误:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL: database "master"
does not exist
(Background on this error at: http://sqlalche.me/e/e3q8)
----------------------------------------------------------------------
Ran 34 tests in 2.011s
FAILED (errors=1)
ERROR: Job failed: exit code 1
其他一些测试用例与master_test
得很好。 但是对于这个测试,它为什么要寻找master
数据库呢?
您必须为测试功能提供上下文。 最好的方法是与工厂合作。 如何做到这一点的一个很好的描述是: http : //alanpryorjr.com/2019-05-20-flask-api-example/ 。 如果你有一个应用程序和一个数据库装置,你可以在你的测试函数中使用它:
from test.fixtures import app, db
def test_get_total_book_price(self, db):
id = 1
response = Book.get_total_book_price(id)
if not response:
self.assertEqual(response, False)
self.assertEqual(response, True)
是的,唯一的区别是函数调用中的db 。 我不能说为什么你的其他测试有效。 我最好的猜测是,您的失败测试是在测试上下文被破坏后执行的。 最好每次都明确说明您的应用程序上下文。
如果其他一切都失败了(并且您可以使用正确的数据库连接访问您的应用程序),您可以使用以下命令手动推送上下文:
from foo import app
def test_get_total_book_price(self, app):
app.app_context().push()
id = 1
response = Book.get_total_book_price(id)
if not response:
self.assertEqual(response, False)
self.assertEqual(response, True)
我想强调的是,您应该使用工厂进行测试。
参考: https : //flask.palletsprojects.com/en/1.0.x/appcontext/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.