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

如何用Python的mock_open模拟同一文件的读写更新场景

问题分析与解决方案

你的测试代码核心问题是重复patch了同一个builtins.open:第二个@patch会完全覆盖第一个,导致你定义的read_mock根本不会被执行,所有open调用都会走第二个mock,这就是断言失败的原因。

正确的做法是用单个mock_open实例来模拟文件的两次打开(读和写),同时跟踪读写的内容,具体实现如下:

修正后的测试代码

import unittest
from unittest.mock import patch, mock_open
import json
# 替换成你的实际模块名
from your_module import simple_read_write

class Example(unittest.TestCase):
    @patch("builtins.open", new_callable=mock_open, read_data=json.dumps({"change": "old data"}))
    def test_simple_read_write(self, mock_file):
        # 执行待测试函数
        simple_read_write()

        # 验证文件被按顺序打开两次:先读再写
        mock_file.assert_has_calls([
            unittest.mock.call("file", "r"),
            unittest.mock.call("file", "w")
        ], any_order=False)

        # 捕获并验证写入的内容(避免JSON格式差异导致的断言失败)
        # 拼接所有write调用的内容(json.dump可能分多次写入)
        written_content = "".join(call.args[0] for call in mock_file().write.call_args_list)
        # 解析成字典后对比,比直接断言字符串更可靠
        written_data = json.loads(written_content)
        self.assertEqual(written_data, {"change": "some content"})

关键细节说明

  1. 单个mock实例覆盖所有调用:
    一个mock_open实例会记录所有open调用的参数和顺序,用assert_has_calls可以精准验证两次打开的模式和路径是否正确。

  2. 避免JSON格式陷阱:
    json.dump生成的字符串可能和json.dumps直接生成的有格式差异(比如缩进、空格),所以捕获写入内容后解析成字典再对比,能避免无意义的断言失败。

  3. 正确获取write调用记录:
    mock_file()返回的是模拟的文件对象实例,它的write方法会被json.dump调用,通过call_args_list可以获取所有写入的内容片段并拼接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:35:08