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

Python 3.5中如何正确Mock Socket的recv方法并处理settimeout失效问题

Python 3.5中如何正确Mock Socket的recv方法并处理settimeout失效问题

我来帮你分析并解决这两个问题,这都是Python unittest Mock中容易踩的细节坑:

问题1:print(data)显示MagicMock对象而非空字符串

这个问题的核心是没有正确Mock with语句中socket对象的__enter__方法。

原代码里用了with socket.socket(...) as client_socket:,这个语法糖会自动调用socket实例的__enter__方法,把返回值赋值给client_socket。而你的Mock代码只创建了socket类的Mock实例,但没指定__enter__的返回值,导致client_socket实际上是个未配置的MagicMock对象,它的recv().decode()自然也会返回MagicMock实例,而非你期望的空字符串。

修正方法很简单,在Mock时让__enter__返回我们配置好的socket Mock实例:

@patch('socket_example.socket.socket')
def test_send_recv(self, mock_socket):
    # 获取socket类的实例Mock
    mock_socket_instance = mock_socket.return_value
    # 关键:让with语句中的__enter__返回这个实例本身
    mock_socket_instance.__enter__.return_value = mock_socket_instance
    # 配置recv返回空字节
    mock_socket_instance.recv.return_value = b''
    
    # 调用被测函数
    result = send_recv('<some-test-xml>')
    
    # 断言返回值为空字符串
    self.assertEqual(result, '')

这样client_socket就会指向我们配置好的Mock实例,recv()返回b'',decode()后就是空字符串,print(data)就会输出空内容,而非MagicMock对象。

问题2:测试死循环需要手动停止

这个问题其实是问题1的连锁反应:因为client_socket是未正确配置的MagicMock,data是MagicMock对象,not data的结果是False(MagicMock实例在布尔判断中默认是True),导致循环条件if "<!--MessageEnd-->" in reply or not data:永远不满足,循环一直执行,所以你需要手动停止测试。

当你按照上面的方法修正Mock后,data会变成空字符串,not data为True,循环会触发break,自然就不会死循环了。

另外补充一个超时场景的测试示例,方便你验证超时分支的逻辑:

@patch('socket_example.socket.socket')
def test_send_recv_timeout(self, mock_socket):
    mock_socket_instance = mock_socket.return_value
    mock_socket_instance.__enter__.return_value = mock_socket_instance
    # 让recv抛出超时异常
    mock_socket_instance.recv.side_effect = socket.timeout
    
    result = send_recv('<some-test-xml>')
    
    self.assertIsNone(result)

最后要注意:确保你的Mock路径和被测文件的导入路径一致(比如@patch('socket_example.socket.socket')中的路径要匹配你的项目结构),Python 3.5的unittest.mock模块功能是完整的,不需要额外依赖。

备注:内容来源于stack exchange,提问作者smark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 18:09:29