使用 pytest
和 MagicMock
模拟数据库操作,并测试假设的 create_user
函数,将用户添加到数据库中。
代码实现
python
from datetime import date
from typing import List, Optional
from unittest.mock import MagicMock
from pydantic import BaseModel, Field, EmailStr
from sqlalchemy.orm import Session
# 假设的枚举类
class GenderType:
DEFAULT = "DEFAULT"
MALE = "MALE"
FEMALE = "FEMALE"
# 假设的 Employment 和 CustomerInfo 类
class Employment(BaseModel):
company: str
position: str
class CustomerInfo(BaseModel):
merchant_id: int
loyalty_points: int
# UserBase 类
class UserBase(BaseModel):
nickname: str = Field(..., description="微信用户昵称")
avatar_url: Optional[str] = Field(None, description="微信用户头像URL")
# User 类
class User(UserBase):
id: int = Field(..., description="用户ID")
union_id: Optional[str] = Field(None, description="微信用户唯一标识")
name: Optional[str] = Field(None, description="用户真实姓名")
gender: Optional[GenderType] = Field(
GenderType.DEFAULT,
description="用户性别,DEFAULT: 默认,MALE: 男,FEMALE: 女",
)
mobile: Optional[str] = Field(None, description="用户手机号")
birthdate: Optional[date] = Field(None, description="用户生日")
email: Optional[EmailStr] = Field(None, description="用户邮箱")
address: Optional[str] = Field(None, description="用户地址")
employments: Optional[List[Employment]] = Field(
None, description="在不同商户中,用户作为员工所拥有的员工组信息"
)
customers: Optional[List[CustomerInfo]] = Field(
None, description="在不同商户中,用户作为顾客所拥有的信息"
)
class Config:
orm_mode = True
# 假设的 create_user 函数
def create_user(db: Session, user_data: UserBase) -> User:
# 模拟创建用户
user = User(
id=1, # 假设生成的用户ID
nickname=user_data.nickname,
avatar_url=user_data.avatar_url,
union_id="mock_union_id",
name="Mock User",
gender=GenderType.DEFAULT,
mobile="1234567890",
birthdate=date(1990, 1, 1),
email="mock@example.com",
address="Mock Address",
employments=[Employment(company="Mock Company", position="Mock Position")],
customers=[CustomerInfo(merchant_id=1, loyalty_points=100)],
)
db.add(user)
db.commit()
return user
# 测试代码
def test_create_user():
# 创建一个模拟的数据库会话
db = MagicMock(spec=Session)
# 创建测试数据
user_data = UserBase(nickname="test_user", avatar_url="https://example.com/avatar.jpg")
# 调用 create_user 函数
user = create_user(db, user_data)
# 断言 db.add 被调用了一次,并且传入的参数是模拟的 user 对象
db.add.assert_called_once_with(user)
# 断言 db.commit 被调用了一次
db.commit.assert_called_once()
# 断言返回的 user 对象有正确的属性
assert user.id == 1
assert user.nickname == "test_user"
assert user.avatar_url == "https://example.com/avatar.jpg"
assert user.union_id == "mock_union_id"
assert user.name == "Mock User"
assert user.gender == GenderType.DEFAULT
assert user.mobile == "1234567890"
assert user.birthdate == date(1990, 1, 1)
assert user.email == "mock@example.com"
assert user.address == "Mock Address"
assert len(user.employments) == 1
assert user.employments[0].company == "Mock Company"
assert user.employments[0].position == "Mock Position"
assert len(user.customers) == 1
assert user.customers[0].merchant_id == 1
assert user.customers[0].loyalty_points == 100
解释
-
UserBase
和User
类: 这些类是基于你提供的代码实现的,包含用户的字段和配置。 -
create_user
函数 : 这是一个假设的函数,它接受一个数据库会话 (db
) 和用户数据 (UserBase
),并创建一个User
对象,将其添加到数据库中。 -
test_create_user
函数 : 这是测试函数,我们在这里测试create_user
函数的行为。• 首先创建一个模拟的数据库会话
db
。• 然后创建测试数据
user_data
。• 调用
create_user
函数,并传入模拟的db
和测试数据。• 使用
assert_called_once_with
来验证db.add
和db.commit
是否被正确调用。• 使用
assert
来验证返回的user
对象具有正确的属性。
运行测试
-
将上述代码保存为一个 Python 文件(例如
test_user.py
)。 -
确保已安装
pytest
。如果未安装,可以使用以下命令安装:bashpip install pytest
-
在终端中运行以下命令来执行测试:
bashpytest test_user.py
预期输出
如果测试通过,会看到类似以下的输出:
============================= test session starts =============================
platform darwin -- Python 3.x.x, pytest-7.x.x, pluggy-1.x.x
rootdir: /path/to/your/project
collected 1 item
test_user.py . [100%]
============================== 1 passed in 0.01s ==============================