Files
DDUp/tests/test_models.py

268 lines
7.3 KiB
Python
Raw Normal View History

2026-01-22 12:57:26 +08:00
"""数据模型测试"""
from datetime import date, time
import pytest
from src.vitals.core.models import (
Exercise,
Meal,
Sleep,
Weight,
UserConfig,
MealType,
ExerciseType,
ActivityLevel,
Goal,
User,
DataClearRequest,
)
class TestExercise:
"""运动记录模型测试"""
def test_create_exercise(self):
"""测试创建运动记录"""
exercise = Exercise(
date=date(2026, 1, 18),
type="跑步",
duration=30,
calories=240,
)
assert exercise.type == "跑步"
assert exercise.duration == 30
assert exercise.calories == 240
def test_exercise_to_dict(self, sample_exercise):
"""测试转换为字典"""
data = sample_exercise.to_dict()
assert data["type"] == "跑步"
assert data["duration"] == 30
assert data["distance"] == 5.0
assert data["date"] == "2026-01-18"
def test_exercise_default_values(self):
"""测试默认值"""
exercise = Exercise()
assert exercise.duration == 0
assert exercise.calories == 0
assert exercise.source == "手动"
class TestMeal:
"""饮食记录模型测试"""
def test_create_meal(self):
"""测试创建饮食记录"""
meal = Meal(
meal_type="早餐",
description="燕麦+鸡蛋",
calories=350,
)
assert meal.meal_type == "早餐"
assert meal.calories == 350
def test_meal_to_dict(self, sample_meal):
"""测试转换为字典"""
data = sample_meal.to_dict()
assert data["meal_type"] == "午餐"
assert data["calories"] == 650
assert data["protein"] == 25.0
def test_meal_with_food_items(self):
"""测试带食物条目的饮食记录"""
meal = Meal(
meal_type="午餐",
description="测试",
food_items=[{"name": "米饭", "calories": 200}],
)
data = meal.to_dict()
assert "米饭" in data["food_items"]
class TestSleep:
"""睡眠记录模型测试"""
def test_create_sleep(self):
"""测试创建睡眠记录"""
sleep = Sleep(
bedtime=time(23, 0),
wake_time=time(7, 0),
duration=8.0,
quality=4,
)
assert sleep.duration == 8.0
assert sleep.quality == 4
def test_sleep_to_dict(self, sample_sleep):
"""测试转换为字典"""
data = sample_sleep.to_dict()
assert data["duration"] == 7.5
assert data["quality"] == 4
assert data["bedtime"] == "23:30:00"
class TestWeight:
"""体重记录模型测试"""
def test_create_weight(self):
"""测试创建体重记录"""
weight = Weight(weight_kg=72.5)
assert weight.weight_kg == 72.5
def test_weight_to_dict(self, sample_weight):
"""测试转换为字典"""
data = sample_weight.to_dict()
assert data["weight_kg"] == 72.5
assert data["body_fat_pct"] == 18.5
class TestUserConfig:
"""用户配置模型测试"""
def test_bmr_calculation_male(self):
"""测试男性 BMR 计算"""
config = UserConfig(
age=28,
gender="male",
height=175.0,
weight=72.0,
)
# Mifflin-St Jeor: 10 * 72 + 6.25 * 175 - 5 * 28 + 5 = 1678
assert config.bmr == 1678
def test_bmr_calculation_female(self):
"""测试女性 BMR 计算"""
config = UserConfig(
age=25,
gender="female",
height=165.0,
weight=55.0,
)
# Mifflin-St Jeor: 10 * 55 + 6.25 * 165 - 5 * 25 - 161 = 1295
assert config.bmr == 1295
def test_bmr_none_when_incomplete(self):
"""测试不完整时 BMR 为 None"""
config = UserConfig(age=28)
assert config.bmr is None
def test_tdee_calculation(self, sample_config):
"""测试 TDEE 计算"""
# BMR * 1.55 (moderate)
expected_tdee = int(sample_config.bmr * 1.55)
assert sample_config.tdee == expected_tdee
def test_tdee_different_activity_levels(self):
"""测试不同活动水平的 TDEE"""
base_config = {
"age": 30,
"gender": "male",
"height": 175.0,
"weight": 70.0,
}
sedentary = UserConfig(**base_config, activity_level="sedentary")
active = UserConfig(**base_config, activity_level="active")
assert sedentary.tdee < active.tdee
def test_config_to_dict(self, sample_config):
"""测试转换为字典"""
data = sample_config.to_dict()
assert data["age"] == 28
assert data["gender"] == "male"
assert data["bmr"] is not None
assert data["tdee"] is not None
class TestEnums:
"""枚举类型测试"""
def test_meal_type_values(self):
"""测试餐次类型"""
assert MealType.BREAKFAST.value == "早餐"
assert MealType.LUNCH.value == "午餐"
assert MealType.DINNER.value == "晚餐"
assert MealType.SNACK.value == "加餐"
def test_exercise_type_values(self):
"""测试运动类型"""
assert ExerciseType.RUNNING.value == "跑步"
assert ExerciseType.SWIMMING.value == "游泳"
def test_activity_level_values(self):
"""测试活动水平"""
assert ActivityLevel.SEDENTARY.value == "sedentary"
assert ActivityLevel.MODERATE.value == "moderate"
def test_goal_values(self):
"""测试目标"""
assert Goal.LOSE.value == "lose"
assert Goal.MAINTAIN.value == "maintain"
assert Goal.GAIN.value == "gain"
class TestUser:
"""用户模型测试"""
def test_user_creation(self):
"""测试创建用户"""
from datetime import datetime
user = User(
name="小明",
created_at=datetime.now(),
)
assert user.name == "小明"
assert user.is_active == False
assert user.id is None
def test_user_to_dict(self):
"""测试用户转换为字典"""
from datetime import datetime
user = User(
id=1,
name="小红",
created_at=datetime(2026, 1, 19, 10, 0, 0),
is_active=True,
)
d = user.to_dict()
assert d["id"] == 1
assert d["name"] == "小红"
assert d["is_active"] == True
assert "created_at" in d
class TestDataClearRequest:
"""数据清除请求模型测试"""
def test_clear_by_range(self):
"""测试按时间范围清除"""
req = DataClearRequest(
user_id=1,
mode="range",
date_from=date(2026, 1, 1),
date_to=date(2026, 1, 15),
)
assert req.mode == "range"
assert req.date_from == date(2026, 1, 1)
def test_clear_by_type(self):
"""测试按类型清除"""
req = DataClearRequest(
user_id=1,
mode="type",
data_types=["exercise", "meal"],
)
assert req.mode == "type"
assert "exercise" in req.data_types
def test_clear_all(self):
"""测试清除全部"""
req = DataClearRequest(
user_id=1,
mode="all",
)
assert req.mode == "all"