SQLAlchemy与仓库模式下TeamRepository单元测试及代码设计求助
问题解决方案
1. 解决 NameError: name 'Team' is not defined
- 确认测试文件已正确导入Team模型类,比如Team定义在
models/team.py,测试代码开头需添加:from models.team import Team - 若使用Mock方式模拟Team,需确保Mock的路径指向TeamRepository实际导入Team的模块路径,而非原模型文件路径(Python导入以模块内引用为准)
2. 正确Mock Team类的实现
使用unittest.mock.patch(或pytest-mock的mocker.patch)指定正确的模块路径,示例如下:
from unittest.mock import patch, MagicMock from repositories.team_repo import TeamRepository def test_get_team_by_id(): # 针对TeamRepository所在模块中导入的Team进行Mock with patch('repositories.team_repo.Team') as mock_team_cls: # 配置Mock的查询返回值 mock_team_instance = MagicMock(id=1, name="测试团队") mock_team_cls.query.filter_by.return_value.first.return_value = mock_team_instance repo = TeamRepository() team = repo.get_team_by_id(1) # 验证调用逻辑 mock_team_cls.query.filter_by.assert_called_once_with(id=1) assert team.id == 1
3. 优化代码设计与表创建隔离
仓库模式的合理优化:依赖注入
让TeamRepository通过构造函数接收数据库会话(Session),而非直接硬依赖模型或数据库连接,降低耦合度:
# repositories/team_repo.py from sqlalchemy.orm import Session from models.team import Team class TeamRepository: def __init__(self, db_session: Session): self.db_session = db_session def get_team(self, team_id: int): return self.db_session.query(Team).filter_by(id=team_id).first() def add_team(self, name: str): new_team = Team(name=name) self.db_session.add(new_team) self.db_session.commit() return new_team
表创建逻辑隔离
将表创建逻辑从仓库类中抽离,单独放在数据库初始化模块(如database.py):
# database.py from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from models.base import Base # 假设Base是所有模型的父类 engine = create_engine("mysql+pymysql://user:password@localhost/db_name") SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) def create_tables(): # 仅在应用初始化时调用,创建所有表 Base.metadata.create_all(bind=engine)
这样TeamRepository只负责CRUD操作,完全符合单一职责原则,测试时可注入Mock的Session对象,彻底隔离真实数据库。
内容的提问来源于stack exchange,提问作者CarolinaMebiom
相关产品推荐
相关产品推荐

