结合unittest和pytest进行虚拟数据库测试

使用 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

解释

  1. UserBase 和 User 类: 这些类是基于你提供的代码实现的,包含用户的字段和配置。

  2. create_user 函数 : 这是一个假设的函数,它接受一个数据库会话 (db) 和用户数据 (UserBase),并创建一个 User 对象,将其添加到数据库中。

  3. test_create_user 函数 : 这是测试函数,我们在这里测试 create_user 函数的行为。

    • 首先创建一个模拟的数据库会话 db。

    • 然后创建测试数据 user_data。

    • 调用 create_user 函数,并传入模拟的 db 和测试数据。

    • 使用 assert_called_once_with 来验证 db.add 和 db.commit 是否被正确调用。

    • 使用 assert 来验证返回的 user 对象具有正确的属性。

运行测试

  1. 将上述代码保存为一个 Python 文件(例如 test_user.py)。

  2. 确保已安装 pytest。如果未安装,可以使用以下命令安装:

    bash 复制代码
    pip install pytest
  3. 在终端中运行以下命令来执行测试:

    bash 复制代码
    pytest 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 ==============================
相关推荐
数据工匠老o6 分钟前
"能用应用层解决的不用存储过程",十年数据库经验总结
数据库·架构
数安旭说11 分钟前
企业终端安全实战:Windows软件管控、正版检测、变更审计与私有软件库落地
windows·企业安全·软件需求·终端安全·软件管理·正版检测·终端审计
AC赳赳老秦15 分钟前
公开音频转写信息提取:OpenClaw 处理发布会与听证会文本并提取核心决策信息
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
老纪的技术唠嗑局34 分钟前
异步索引特性解析:OceanBase 如何提升持续写入场景下的索引检索性能
数据库
老纪的技术唠嗑局39 分钟前
Tibo 谈 Codex:harness 总比模型快一步
数据库·人工智能
猫咪宝妖1 小时前
信息安全工程师 第四级 结构化保护级
网络·数据库·安全
Andreapiki1 小时前
风险审计校招技术栈拆解:SQL、Python、Power BI在2026届JD中的真实权重
数据库·python·sql
nvd111 小时前
从存算一体到现代湖仓:对标传统关系型数据库透视 Bucket + Iceberg + Trino 的物理本质
数据库·bigdata
JosieBook2 小时前
【数据库】MySQL 实战精通系列 · 第8篇:慢查询治理与性能优化实战
数据库·mysql·性能优化
小羊没烦恼!2 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#