如何用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
相关产品推荐
相关产品推荐

