Mock 与单元测试
unittest.mock/MagicMock、patch 替换、副作用、断言调用
Mock 与单元测试
测试不应依赖外部服务——unittest.mock 用假对象替代真实依赖,让测试快速、可重复。
学完本章你将: 掌握 MagicMock、patch 替换、断言调用。
Mock 基础
python
from unittest.mock import Mock
# 创建一个 Mock——任何调用都接受
mock = Mock()
mock.any_method(42) # 不会报错
mock.another("hello")
# 断言调用
mock.any_method.assert_called_once_with(42)
print(mock.any_method.call_count) # 1
patch —— 替换依赖
python
from unittest.mock import patch
def get_user_name(user_id):
# 实际上调用外部 API
resp = requests.get(f"https://api.example.com/users/{user_id}")
return resp.json()["name"]
# 测试——替换 requests.get
@patch("module.requests.get")
def test_get_user_name(mock_get):
mock_get.return_value.json.return_value = {"name": "小明"}
result = get_user_name(1)
assert result == "小明"
mock_get.assert_called_once_with("https://api.example.com/users/1")
MagicMock —— 更智能的 Mock
python
from unittest.mock import MagicMock
# MagicMock 自动实现了 Python 的魔术方法
mock = MagicMock()
len(mock) # 不报错,返回 0
mock[0] = "hello" # 支持下标
for x in mock: # 支持迭代
pass
side_effect —— 模拟异常或多次不同返回值
python
mock = Mock()
mock.get.side_effect = [
"第1次结果",
"第2次结果",
Exception("第3次出错"),
]
print(mock.get()) # "第1次结果"
print(mock.get()) # "第2次结果"
# mock.get() # 抛出 Exception