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

如何用mock.patch装饰器实现sys.stdout转StringIO以记录测试输出?

解决mock.patch装饰器替换sys.stdout为StringIO的报错问题

当你用mock.patch装饰器形式替换sys.stdout为StringIO时,出现Mock object has no attribute 'getvalue'错误,原因是装饰器传递给测试方法的参数是Mock包装对象,而非直接的StringIO实例——而with语句中as绑定的是实际替换的StringIO实例,因此可以正常运行。

以下是两种正确的装饰器写法:

写法一:直接访问被替换后的sys.stdout

直接使用被patch后的sys.stdout来获取输出,无需依赖装饰器传递的参数:

import sys
from unittest import mock
from io import StringIO
import unittest

class TestStdout(unittest.TestCase):
    @mock.patch('sys.stdout', new_callable=StringIO)
    def test_stdout(self, _):
        print('OUTPUT')
        # 直接访问sys.stdout,此时它已经是StringIO实例
        r = sys.stdout.getvalue()
        print(r)

写法二:用lambda确保每次创建新的StringIO实例

通过new参数配合lambda,让mock.patch每次都生成新的StringIO实例,此时传递给测试方法的参数就是该实例:

import sys
from unittest import mock
from io import StringIO
import unittest

class TestStdout(unittest.TestCase):
    @mock.patch('sys.stdout', new=lambda: StringIO())
    def test_stdout(self, recorded_output):
        print('OUTPUT')
        r = recorded_output.getvalue()
        print(r)

注意事项

  • Python 3中StringIO来自io模块,Python 2中来自StringIO模块,需根据版本正确导入。
  • 如果是在非unittest.TestCase的普通函数中使用装饰器,直接用@mock.patch('sys.stdout', new_callable=StringIO)即可,传递的参数就是StringIO实例,不会出现该错误——错误大多出现在装饰unittest测试类方法的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 09:23:14