我想为我的应用程序的一些功能编写单元测试,为此我需要模拟对我的数据库的一些SQLAlchemy调用。问题是,每次我尝试它都会给我一个错误:";RuntimeError:找不到应用程序">
这是我想要单元测试的功能:
def update_user(user_uid, new_info):
user = db.session.query(User).filter_by(uid=user_uid).first()
# check if values are the same before changing
# ensure unique username and email for all users
if user.username != new_info["username"]:
if db.session.query(User).filter_by(username=new_info["username"]).first() is not None:
return {"success": "False", "code": "400", "result": "Username already taken"}
else:
user.username = new_info["username"]
if user.email != new_info["email"]:
if db.session.query(User).filter_by(email=new_info["email"]).first() is not None:
return {"success": "False", "code": "400", "result": "Email already taken"}
else:
user.email = new_info["email"]
if user.subscription_uid != new_info["subscription_uid"]:
user.subscription_uid = new_info["subscription_uid"]
# password only has length if being changed
if len(new_info["password"]):
hashed = bcrypt.hashpw(new_info["password"].encode("utf-8"), bcrypt.gensalt())
user.password = hashed.decode("utf-8")
db.session.commit()
return {"success": "True", "code": "200", "result": "User updated successfully"}
我想模拟所有的
db.session
我试过这样做:
class TestUser(unittest.TestCase):
def test_update_user(self):
user_db = {"username": "user", "email": "user@test.com", "subscription_uid": "1", "password": ""}
info_user_same_username = {"username": "user", "email": "new_user@test.com", "subscription_uid": "1", "password": ""}
info_user_same_email = {"username": "new_user", "email": "user@test.com", "subscription_uid": "1", "password": ""}
info_new_user = {"username": "new_user", "email": "new_user@test.com", "subscription_uid": "2", "password": "new_password"}
with mock.patch('flask_sqlalchemy._QueryProperty.__get__') as mock_user:
mock_user.return_value = user_db
response_correct = {"success": "True", "code": "200", "result": "User updated successfully"}
response_same_username = {"success": "False", "code": "400", "result": "Email already taken"}
response_same_email = {"success": "False", "code": "400", "result": "Username already taken"}
response = update_user(1, info_new_user)
response_username = update_user(1, info_user_same_username)
response_email = update_user(1, info_user_same_email)
self.assertEqual(response, response_correct)
self.assertEqual(response_username, response_same_username)
self.assertEqual(response_email, response_same_email)
但我得到了这个错误:
Traceback (most recent call last):
File "C:UsersgustaOneDriveDocumentsPomelobackendpomelo_backendteststest_User.py", line 23, in test_update_user
response = update_user(1, info_new_user)
File "C:UsersgustaOneDriveDocumentsPomelobackendpomelo_backenduser.py", line 8, in update_user
user = db.session.query(User).filter_by(uid=user_uid).first()
File "<string>", line 2, in query
File "C:UsersgustaOneDriveDocumentsPythonbackendlibsite-packagessqlalchemyormscoping.py", line 105, in _proxied
return self.registry()
File "C:UsersgustaOneDriveDocumentsPythonbackendlibsite-packagessqlalchemyutil_collections.py", line 1010, in __call__
return self.registry.setdefault(key, self.createfunc())
File "C:UsersgustaOneDriveDocumentsPythonbackendlibsite-packagessqlalchemyormsession.py", line 4058, in __call__
return self.class_(**local_kw)
File "C:UsersgustaOneDriveDocumentsPythonbackendlibsite-packagesflask_sqlalchemy__init__.py", line 174, in __init__
self.app = app = db.get_app()
File "C:UsersgustaOneDriveDocumentsPythonbackendlibsite-packagesflask_sqlalchemy__init__.py", line 1043, in get_app
'No application found. Either work inside a view function or push'
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
我尝试了其他一些方法:-使用炼金术模拟-@patch('flask_sqlalchemy._QueryProperty.get'(
但总是相同的错误信息。
您试图在应用程序上下文之外使用SQLAlchemy,这是不允许的。
要在测试中推送应用程序上下文,您必须导入您的应用程序:
from module import app
在烧瓶中,您可以在应用程序配置中将TESTING
设置为True
app.config['TESTING'] = True
然后在测试内部,您必须推送应用程序上下文:
def test_something(self):
with app.test_client() as client:
# do something
这在测试路线时特别有用,因为你可以向你的应用程序发送请求并测试响应,即:
def test_something(self):
with app.test_client() as client:
res = client.get('/users')
res_html = res.get_data(as_text=True)
self.assertEqual(res.status_code, 200)
self.assertIn('<div id="target-div">', res_html)