使用 SQLAlchemy 进行单元测试时"RuntimeError: No application found."



我想为我的应用程序的一些功能编写单元测试,为此我需要模拟对我的数据库的一些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)

最新更新