python - 如何在不必模拟整个会话的情况下模拟 SQLALCHEMY 查询?
问题描述
我正在为我的应用程序中的一个函数编写一些单元测试,该函数充当我的 tictactoe 游戏的服务器。app.py 托管服务器,在其中,我有一个名为 on_winner 的函数。on_winner 基本上检查从客户端从套接字发出的用户名是赢家还是输家,它在数据库中查询他们的名字,更新他们的分数,然后将该数据推回数据库。
我只是在写一个单元测试来检查这个函数的逻辑。在我的测试功能中,我可以成功修补除 DB.session.query 之外的所有内容。我尝试使用谷歌搜索该主题,但我看到的许多示例都显示了带有 self 以外的参数的测试函数。我不确定我应该在这里写什么。
这是 app.py 中的函数:
def on_winner(data):
"""Tells everybody who'se won, and returns updated scores."""
winner = DB.session.query(
models.Person).filter_by(username=data['username'])
if data['status'] == 'winner':
winner.score += 1
elif data['status'] == 'loser':
winner.score -= 1
DB.session.add(winner)
DB.session.commit()
ordered_scores = DB.session.query(models.Person).order_by(
models.Person.score.desc())
ordered_users = ordered_append(ordered_scores)
#SOCKETIO.emit('winner', {'ordered_users': ordered_users},
# broadcast=True,
# include_self=True)
return ordered_users
这是我的测试文件:
"""This file just tests that my app
correctly updates the score of winner
and loser"""
import unittest
from unittest.mock import patch
from app import on_winner
import models
INPUT = "user"
EXPECTED_OUTPUT = "expected"
USERNAME = 'username'
STATUS = 'status'
SCORE = 'score'
LETTER = 'letter'
class WinnerTestCase(unittest.TestCase):
"""Tests that the add_to_db function is working properly"""
def setUp(self):
self.success_test_params = [
{
INPUT: {USERNAME : 'Kevin', STATUS : 'winner'},
EXPECTED_OUTPUT: [{USERNAME : 'Joe', SCORE : 101, LETTER : 'O'}, {USERNAME : 'Kevin', SCORE : 101, LETTER : 'X'}, {USERNAME : 'Irene', SCORE : 100, LETTER : 'X'}]
},
{
INPUT: {USERNAME : 'Irene', STATUS : 'loser'},
EXPECTED_OUTPUT: [{USERNAME : 'Joe', SCORE : 101, LETTER : 'O'}, {USERNAME : 'Kevin', SCORE : 101, LETTER : 'X'}, {USERNAME : 'Irene', SCORE : 100, LETTER : 'X'}]
},
{
INPUT : {USERNAME : 'Joe', STATUS : 'winner'},
EXPECTED_OUTPUT: [{USERNAME : 'Joe', SCORE : 102, LETTER : 'O'}, {USERNAME : 'Kevin', SCORE : 101, LETTER : 'X'}, {USERNAME : 'Irene', SCORE : 100, LETTER : 'X'}]
}
]
KEVIN = models.Person(username='Kevin', score=100, letter='X')
JOE = models.Person(username='Joe', score=101, letter='O')
IRENE = models.Person(username='Irene', score=100, letter='X')
self.initial_db_mock = [KEVIN, JOE, IRENE]
def mocked_add(self, user):
"""Mocks db.session.add"""
def mocked_commit(self):
"""Mocks db.session.commit"""
def mocked_query(self,username):
"""Mocks query all"""
print("You're in mocked_query")
for person in self.initial_db_mock:
if person[USERNAME]==username:
return person
def mocked_emit(self):
"""Mocks emit"""
def ordered_mocked_query(self):
"""This function returns the list of users in descending order"""
return sorted(self.initial_db_mock, key = lambda i : i[SCORE], reverse=True)
def test_on_winner(self):
"""Tests the add functions. Mocks everything"""
for test in self.success_test_params:
with patch('app.DB.session.add', self.mocked_add):
with patch('app.DB.session.commit', self.mocked_commit):
with patch('app.DB.session.query') as mocked_db_query:
#with patch('SOCKETIO.emit', self.mocked_emit):
mocked_db_query.filter_by.return_value = self.mocked_query
mocked_db_query.order_by.return_value = self.ordered_mocked_query
actual_result = on_winner(test[INPUT])
expected_result = test[EXPECTED_OUTPUT]
print (actual_result," ",expected_result)
self.assertEqual(len(actual_result), len(expected_result))
self.assertEqual(actual_result, expected_result)
if __name__ == '__main__':
unittest.main()
解决方案
推荐阅读
- c - 即使 struct termios c_cc[VMIN]=1,两个线程和终端也不会阻塞
- client - RDP 会话可以看到有关主机的哪些信息
- apache-spark - 在 SparkR 中计算 groupBy 内的中位数
- java - 使用 Mockito.doNothing() 进行事务注释
- reactjs - 我的 localhost.5000 和内部服务器有什么问题?
- linkedin-api - 获取Linkedin公司页面帖子(ugcPosts)
- apexcharts - 组合图表顶点图表中的自定义位置
- javascript - 在 React 中使用 useContext 和 useReducer 创建新的键值对
- flutter - Flutter 从 firebase_admob 切换到 google_mobile_ads
- java - 从 Apache Kerby TGTTicket 检索字符串令牌