You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python unittest的mock功能正确模拟类的依赖项

你当前的测试代码中设置mock_data.return_value无法替换get_posts的返回值,测试运行会直接报错,核心原因是mock的目标对象完全错误。

错误原因分析

你已经将Mock后的HttpClient实例注入到了Post类中,Post.get_posts方法调用的是Mock实例的request方法,全程不会触发真实的requests.get逻辑,因此你patch的requests.get完全不会被调用,设置的返回值自然不会生效。
另外setUp方法上的@patch('app.client.HttpClient')也属于冗余代码,你没有用到patch生成的模拟类,直接手动创建了MagicMock实例注入。

正确的测试实现思路

你要测试的是Post类的业务逻辑,只需要模拟依赖的HttpClient.request方法的返回值即可,不需要触碰底层的requests库:

import unittest
from unittest.mock import MagicMock
from app.data import Post
from app.client import HttpClient

class TestPost(unittest.TestCase):
    def setUp(self):
        # 构造模拟的HttpClient实例,直接注入到Post
        self.mock_http = MagicMock(autospec=HttpClient)
        self.mock_post = Post(self.mock_http)

    def test_get_posts_success(self):
        # 构造模拟响应,匹配代码中用到的ok属性和json()方法
        mock_resp = MagicMock()
        mock_resp.ok = True
        mock_resp.json.return_value = {
            'postId': 1,
            'title': 'My title',
            'description': 'Post description'
        }
        # 给模拟的request方法设置返回值
        self.mock_http.request.return_value = mock_resp

        resp = self.mock_post.get_posts(1)
        # 断言返回值符合预期
        assert resp['postId'] == 1
        # 额外校验request方法被调用时传入的参数正确(可选)
        self.mock_http.request.assert_called_once_with(
            method="GET",
            url="https://jsonplaceholder.typicode.com/posts/1"
        )
    
    def test_get_posts_failed(self):
        # 测试请求失败的场景
        mock_resp = MagicMock()
        mock_resp.ok = False
        mock_resp.status_code = 404
        self.mock_http.request.return_value = mock_resp

        resp = self.mock_post.get_posts(999)
        assert resp == 404

执行过程说明

  1. 初始化阶段:手动创建HttpClient的模拟实例注入到Post类,Post内部持有的client就是该模拟对象,而非真实的HTTP客户端
  2. 调用被测方法:self.mock_post.get_posts(1)执行时,内部调用self.client.request,实际是调用模拟对象的方法,直接返回你预先设置的mock_resp,不会发起任何真实网络请求
  3. 逻辑校验:代码判断mock_resp.ok的状态,走对应分支返回结果,完成业务逻辑的测试

额外补充

如果你要测试的是HttpClient类本身的逻辑,才需要patchrequests.get/requests.post,验证HttpClient.request方法是否会根据传入参数正确调用对应的requests方法。

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:36:03