如何为Python类的序列化save方法编写Unittest单元测试?
针对save方法的单元测试编写方案
先修正原代码的已知问题
你提供的save方法存在两处会直接导致运行失败的问题,需要先修复再编写测试:
- 未导入json模块,使用
json.dump前需要先加import json - 循环前未初始化
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
相关产品推荐
相关产品推荐

