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

Python单元测试:Pytest中Mock json.dumps()遇序列化错误的解决咨询

问题原因及解决方法

为什么会出现这个问题?

  1. Patch目标错误:mock的核心规则是patch被测试代码实际引用的那个对象,而非原始模块的对象。比如你测试代码里patch了json.dumps,但如果被测试函数是在自身模块内导入json(比如import json写在被测试模块里),那实际调用的是该模块内的json.dumps引用,直接patch全局的json.dumps不会生效。
  2. Mock返回值不可序列化:默认情况下,MagicMock实例本身不属于JSON可序列化类型。如果你的代码在调用json.dumps后,还有后续逻辑需要把返回值再次序列化(或传递给要求JSON格式的场景),就会触发TypeError。

其他patch能正常工作,是因为那些被mock的函数返回的MagicMock没有被后续代码要求做序列化操作,或者它们的返回值本身是基础类型(比如字符串、数字),不会触发序列化错误。

解决步骤

1. 确定正确的Patch目标

假设你的被测试代码在your_module.py里:

  • 如果代码里是import json后用json.dumps,就patchyour_module.json.dumps
  • 如果代码里是from json import dumps后用dumps,就patchyour_module.dumps

2. 指定Mock的返回值或保留真实行为

方法一:直接指定返回值

如果只需要验证json.dumps的调用情况,不需要真实序列化,直接给mock指定合法的JSON字符串返回值:

from unittest import mock
import pytest
from your_module import your_function

def test_your_function():
    with mock.patch("your_module.json.dumps") as mock_dumps:
        # 指定返回值为合法JSON字符串
        mock_dumps.return_value = '{"name": "test", "value": 123}'
        result = your_function({"name": "test", "value": 123})
        
        # 验证调用参数和次数
        mock_dumps.assert_called_once_with({"name": "test", "value": 123})
        assert result == '{"name": "test", "value": 123}'

方法二:保留真实序列化行为

如果需要json.dumps正常工作,同时跟踪调用情况,可以用side_effect调用原始方法:

import json
from unittest import mock
from your_module import your_function

def test_your_function_with_real_serialize():
    with mock.patch("your_module.json.dumps") as mock_dumps:
        # 让mock调用原始的json.dumps方法
        mock_dumps.side_effect = json.dumps
        result = your_function({"name": "test", "value": 123})
        
        mock_dumps.assert_called_once_with({"name": "test", "value": 123})
        assert result == '{"name": "test", "value": 123}'

方法三:Mock整个json库并指定dumps的返回值

如果要mock整个json库,需要给json.dumps单独指定返回值,而非依赖默认的MagicMock:

from unittest import mock
import pytest
from your_module import your_function

def test_your_function_mock_whole_json():
    with mock.patch("your_module.json") as mock_json:
        # 给dumps指定返回值
        mock_json.dumps.return_value = '{"name": "test", "value": 123}'
        result = your_function({"name": "test", "value": 123})
        
        mock_json.dumps.assert_called_once_with({"name": "test", "value": 123})
        assert result == '{"name": "test", "value": 123}'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:27:13