Python测试辅助工具: Mock模拟数据库查询、网络请求、模块依赖

很好,这是非常实用的场景!下面我将分别为你提供:

  1. ✅ 模拟数据库(如数据库连接/查询)
  2. ✅ 模拟类之间的依赖(如服务A依赖服务B)
  3. ✅ 模拟网络请求(如调用第三方API)

这些都使用 unittest.mock 实现,帮助你写出快速、隔离、可控的测试



✅ 1. 模拟数据库操作

场景:UserService 查询数据库中的用户数据

# db.py
class DB:
    def get_user(self, user_id):
        # 实际上是执行 SQL 查询
        return {"id": user_id, "name": "Alice"}
# user_service.py
from db import DB

class UserService:
    def __init__(self, db: DB):
        self.db = db

    def get_username(self, user_id):
        user = self.db.get_user(user_id)
        return user["name"]

✅ 测试中 mock 掉 DB.get_user

# test_user_service.py
import unittest
from unittest.mock import Mock
from user_service import UserService

class TestUserService(unittest.TestCase):
    def test_get_username(self):
        mock_db = Mock()
        mock_db.get_user.return_value = {"id": 1, "name": "Bob"}

        service = UserService(mock_db)
        name = service.get_username(1)

        self.assertEqual(name, "Bob")
        mock_db.get_user.assert_called_with(1)

if __name__ == '__main__':
    unittest.main()


✅ 2. 模拟类之间的依赖关系

场景:OrderService 依赖 PaymentService

# payment.py
class PaymentService:
    def charge(self, user_id, amount):
        return True  # 实际上是调用支付接口
# order.py
from payment import PaymentService

class OrderService:
    def __init__(self, payment_service: PaymentService):
        self.payment = payment_service

    def place_order(self, user_id, amount):
        success = self.payment.charge(user_id, amount)
        return "success" if success else "fail"

✅ 测试中 mock PaymentService

# test_order.py
import unittest
from unittest.mock import Mock
from order import OrderService

class TestOrderService(unittest.TestCase):
    def test_place_order_success(self):
        mock_payment = Mock()
        mock_payment.charge.return_value = True

        service = OrderService(mock_payment)
        result = service.place_order(1, 100)

        self.assertEqual(result, "success")
        mock_payment.charge.assert_called_once_with(1, 100)

if __name__ == '__main__':
    unittest.main()


✅ 3. 模拟网络请求(requests.get/post)

场景:天气查询 API 调用第三方天气接口

# weather.py
import requests

def get_weather(city):
    response = requests.get(f"https://api.weather.com/{city}")
    return response.json()

✅ 测试中 mock requests.get

# test_weather.py
import unittest
from unittest.mock import patch

from weather import get_weather

class TestWeather(unittest.TestCase):
    @patch('weather.requests.get')
    def test_get_weather(self, mock_get):
        mock_get.return_value.json.return_value = {"temp": 30}

        result = get_weather("beijing")
        self.assertEqual(result["temp"], 30)
        mock_get.assert_called_once_with("https://api.weather.com/beijing")

if __name__ == '__main__':
    unittest.main()


🧠 总结:三类依赖 mock 方法对比

场景使用对象使用方式
数据库查询自定义类或接口使用 Mock() 替换依赖类
类之间调用类或接口对象Mock() 替代注入的依赖
网络请求requests.get@patch('xxx.requests.get') 替换


如果你使用的是 SQLAlchemyDjango ORMFastAPIFlask 或其他框架,我也可以给你贴合框架的 Mock 示例。你需要我基于哪个框架或工具补充?

文章标签:

评论(0)