单元测试中如何Mock函数内部读取的JSON文件?
如何Mock函数中的JSON文件进行单元测试
原函数
def get_env_id(id): with open(pathlib.Path(__file__).parent / 'srm.json') as file: data = json.load(file) return data.get(id)
测试目标
Mock上述函数读取的srm.json文件,使用以下预设JSON内容:
{"id":{"0":1,"1":2,"2":3},"value":{"0":20,"1":30,"2":40}}
解决方案
使用Python标准库的unittest.mock模块可以轻松实现文件Mock,下面提供两种实用方案:
方案1:Mock open函数返回模拟文件对象
这种方式模拟真实的文件读取流程,适合需要验证文件操作的场景:
import unittest from unittest.mock import mock_open, patch import json import pathlib from your_module import get_env_id # 替换为实际模块名 class TestGetEnvId(unittest.TestCase): def test_get_env_id(self): # 定义Mock的JSON内容字符串 mock_json_str = '{"id":{"0":1,"1":2,"2":3},"value":{"0":20,"1":30,"2":40}}' # 替换builtins.open为模拟函数,返回预设内容 with patch("builtins.open", mock_open(read_data=mock_json_str)): # 验证正常取值 self.assertEqual(get_env_id("id"), {"0":1,"1":2,"2":3}) self.assertEqual(get_env_id("value"), {"0":20,"1":30,"2":40}) # 验证不存在的key返回None self.assertIsNone(get_env_id("invalid_key"))
方案2:直接Mock json.load的返回值
如果只关注JSON解析后的结果,无需验证文件操作,这种方式更简洁:
import unittest from unittest.mock import patch from your_module import get_env_id # 替换为实际模块名 class TestGetEnvId(unittest.TestCase): def test_get_env_id(self): # 定义Mock的解析后数据 mock_data = {"id":{"0":1,"1":2,"2":3},"value":{"0":20,"1":30,"2":40}} # 替换json.load,直接返回预设字典 with patch("json.load", return_value=mock_data): self.assertEqual(get_env_id("id"), {"0":1,"1":2,"2":3}) self.assertEqual(get_env_id("value"), {"0":20,"1":30,"2":40}) self.assertIsNone(get_env_id("invalid_key"))
注意事项
- 务必将
your_module替换为定义get_env_id函数的实际模块名称 - 方案1更贴近真实执行流程,适合需要确认文件是否被正确打开的测试;方案2聚焦业务逻辑,代码更简洁
内容的提问来源于stack exchange,提问作者shan
相关产品推荐
相关产品推荐

