您的位置:首页 >Python模拟复杂对象:unittest.mock与pytest注入教程
发布于2026-04-11 阅读(0)
扫一扫,手机访问
mock.patch没生效最常见的原因是目标路径写错,应patch被测函数实际访问的位置而非import位置;可用patch.object更安全,side_effect控制多返回值,assert_called系列验证调用,fixture封装patch避免重复。

最常见的原因是 patch 的目标位置写错了——不是写被测试代码里 import 的地方,而是写「被测试对象实际访问它的地方」。比如你在 utils.py 里写了 requests.get(),但测试时却 patch requests.get 在 test_utils.py 中的导入路径,那 mock 就不会触发。
实操建议:
patch('module_name.ClassName.method_name'),其中 module_name 是被测函数所在模块(如 utils),不是你 import 它的地方app.services.api_client 里调用了 httpx.post,就该 patch 'app.services.api_client.httpx.post'patch.object 更安全:比如 patch.object(httpx, 'post'),避免字符串路径出错单次调用返回固定值不够用,比如一个函数里两次调用 json.loads(),第一次成功、第二次抛异常,就得控制返回行为。
实操建议:
side_effect:传列表(按调用顺序返回)、异常类(如 ValueError)、或函数(可带参数做判断)mock_obj.method.side_effect = [True, False, ValueError('timeout')] —— 第三次调用直接 raiselambda x: {'id': 1} if 'user' in x else {}return_value 和 side_effect 互斥,设了后者,前者会被忽略光 mock 不验证,等于白 mock。容易漏掉参数拼错、调用次数不对、甚至根本没调用。
实操建议:
assert_called()、assert_called_once()、assert_not_called() 快速确认是否触发mock_obj.method.assert_called_with(url='https://api.example.com', timeout=5)mock_obj.method.assert_has_calls([call(...), call(...)], any_order=False)call 要从 unittest.mock 导入,pytest 不自带把 patch 写进每个 test 函数太重复;全塞进 conftest.py 又容易过度共享、干扰其他测试。
实操建议:
@pytest.fixture + with patch(...) 或 patch.start()/stop()'function',避免跨测试污染;需要共享时再升到 'module'AttributeError,先关掉试试spec_set=True,访问不存在属性会立刻报错真实项目里,mock 的边界往往比想象中模糊——比如你以为只 mock 了数据库,结果 ORM 自动触发了缓存 client 的初始化。多打一行 print(mock_obj.__dict__) 或用 mock_obj.method.call_args_list 看看到底发生了什么,比猜快得多。
下一篇:鼠标指针卡顿怎么调?提速技巧分享
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9