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

如何为Python类的序列化save方法编写Unittest单元测试?

针对save方法的单元测试编写方案

先修正原代码的已知问题

你提供的save方法存在两处会直接导致运行失败的问题,需要先修复再编写测试:

  1. 未导入json模块,使用json.dump前需要先加import json
  2. 循环前未初始化Dict变量,直接赋值会抛出NameError,需要在for循环前添加Dict = {}

修复后的完整代码参考:

import json
class A():
    __file_path = "file.json"
    __objects = {}

    def save(self):
        """
        serializes __objects to the JSON file: __file_path
        Note:
        __objects is a dictionary of Keys: numbers
        Values: object of class B with a get_dict() method returning dictionary representation a B.object
        """
        Dict = {}
        for k, v in self.__objects.items():
            Dict[k] = v.get_dict()
        with open(self.__file_path, 'w') as fd:
            json.dump(Dict, fd)

单元测试实现思路

单元测试要保证依赖隔离,不需要依赖真实的B类实现,也不需要生成真实的磁盘文件,我们可以通过unittest.mock模拟依赖、拦截文件写入操作。
Python的类私有属性通过名称修饰机制实现,类外访问需要用_类名__属性名的格式,比如这里的_A__objects、_A__file_path。

完整测试代码示例

import unittest
from unittest.mock import patch, MagicMock
import json
from your_module import A  # 替换为你实际存放A类的模块名

class TestASaveMethod(unittest.TestCase):
    def setUp(self):
        # 每个用例执行前重置A类的私有属性,避免用例间数据污染
        self.instance_a = A()
        A._A__objects = {}
        A._A__file_path = "file.json"

    def test_save_with_empty_objects(self):
        """测试__objects为空时,save写入空JSON对象"""
        # 模拟open函数,不生成真实文件
        with patch("builtins.open", new_callable=MagicMock) as mock_open:
            self.instance_a.save()
            # 校验是否以正确模式打开指定路径
            mock_open.assert_called_once_with("file.json", "w")
            # 获取模拟的文件句柄
            mock_fd = mock_open.return_value.__enter__.return_value
            # 校验写入内容是否为空对象
            written_content = json.loads(mock_fd.write.call_args[0][0])
            self.assertEqual(written_content, {})

    def test_save_with_multiple_b_instances(self):
        """测试__objects存在多个B类实例时,序列化结果符合预期"""
        # 模拟B类实例,不需要依赖真实B类实现
        mock_b1 = MagicMock()
        mock_b1.get_dict.return_value = {"id": 1, "name": "test_obj1"}
        mock_b2 = MagicMock()
        mock_b2.get_dict.return_value = {"id": 2, "name": "test_obj2"}
        # 给私有属性__objects赋值测试数据
        A._A__objects = {
            1: mock_b1,
            2: mock_b2
        }

        with patch("builtins.open", new_callable=MagicMock):
            self.instance_a.save()
            # 校验每个B实例的get_dict方法都被调用了一次
            mock_b1.get_dict.assert_called_once()
            mock_b2.get_dict.assert_called_once()
            # 校验写入的JSON内容是否符合预期
            expected_data = {
                "1": {"id": 1, "name": "test_obj1"},
                "2": {"id": 2, "name": "test_obj2"}
            }
            mock_fd = open.return_value.__enter__.return_value
            written_content = json.loads(mock_fd.write.call_args[0][0])
            self.assertEqual(written_content, expected_data)

if __name__ == "__main__":
    unittest.main()

可扩展的测试场景

  • 测试自定义文件路径场景:修改_A__file_path为自定义路径,校验save方法会写入对应路径
  • 测试异常场景:比如模拟文件没有写入权限,校验save方法是否抛出预期异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:09:03