[英]Usage of app_context when testing with Flask-SQLAlchemy
我正在从仅使用Flask
和SQLAlchemy
与自己的数据库连接设置与引擎和 session 转向使用Flask-SQLAlchemy
。 我有很多看起来像这样的测试:
def setUp(self):
self.app = create_app()
self.client = self.app.test_client()
def test_put_example(self):
assert len(Example.query.all()) == 0
data = [{
"id": 1,
"valid": True,
}, {
"id": 2,
"valid": True,
}, {
"id": 3,
"valid": True,
}, {
"id": 4,
"valid": True,
}, {
"id": 5,
"valid": False, # Lets assume this value is illegal in some way and will not be accepted
}]
response = self.client.open('/v1/example', method='PUT', data=json.dumps(data))
json_value = json.loads(response.data)
assert not json_value['success'] and json_value['message'] == 'Unauthorized'
assert len(Example.query.all()) == 0
在这里,我假设在测试端点之前数据库中有 0 个条目,在测试端点之后假设有 0 个条目。 当分别使用Flask
和SQLAlchemy
时,这工作得很好,因为如果在请求期间没有commit
,事务会在请求结束时隐式回滚。
迁移到Flask-SQLAlchemy
后,我很难找到执行此类测试的好方法。 我希望不必过多地处理单个测试,但是如果我改变我的setUp
,例如这样:
def setUp(self):
self.app = create_app()
self.app.app_context().push()
self.client = self.app.test_client()
然后最后一次检查assert len(Example.query.all()) == 0
失败,因为它显然没有回滚有效的元素,所以我得到4
作为长度。
应该注意的是,在运行应用程序时,我确实似乎得到了我想要的回滚,只是在测试期间没有。
我看到我可能会在每个Example.query
调用之前with self.app.app_context()
,但这意味着对单个测试进行许多更改,所以我宁愿不必这样做,以及对我对如何正确使用AppContext
的理解不完全有信心。
有什么方法可以在端点测试之前和之后为我的查询正确提供AppContext
而不改变单个测试并且仍然让test_client
回滚?
我不确定这是一种理想的方法,但到目前为止我最终做的是:
我不再保留test_client
,而是包装对它的调用以使用它自己的app_context
按需初始化。 我确实推送了一个app_context
,它将被我运行的查询使用。
def setUp(self):
self.app = create_app()
self.context = self.app.app_context()
self.context.push()
def tearDown(self):
self.context.pop()
def client_open(self, url, method, data):
with self.app.app_context():
with self.app.test_client() as client:
result = client.open(url, method=method, data=json.dumps(data))
def test_put_example(self):
assert len(Example.query.all()) == 0
data = [{
"id": 1,
"valid": True,
}, {
"id": 2,
"valid": True,
}, {
"id": 3,
"valid": True,
}, {
"id": 4,
"valid": True,
}, {
"id": 5,
"valid": False, # Lets assume this value is illegal in some way and will not be accepted
}]
response = client_open('/v1/example', 'PUT', json.dumps(data)) # Wrapped call to test_client using own app_context
json_value = json.loads(response.data)
assert not json_value['success'] and json_value['message'] == 'Unauthorized'
assert len(Example.query.all()) == 0
这样app_context
使用的test_client
在使用后会被拆掉,而查询使用的app_context
在整个测试过程中都是可用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.