如何编写Python unittest测试长列表动态缩进,避免巨型字符串?
解决方法
核心思路是动态生成测试用的大量条目,不用手动编写巨型字符串,下面是两种实用实现方式:
方法一:用字符串生成器构造模拟文件内容
直接通过循环生成指定数量的记录,再用换行符拼接成模拟的文件内容,代码简洁直观:
from unittest.mock import patch, mock_open from textwrap import dedent def test_thousands_of_items(self): """测试数千条记录的编号对齐逻辑""" # 自定义要测试的条目数量,比如1000条 item_count = 1000 # 动态生成模拟的文件内容 read_data = "\n".join([f"Item {i+1} (2022-04-25)" for i in range(item_count)]) with patch("todo.open", mock_open(read_data=read_data)): Handler().list() # 注意原函数是list,不是测试代码里的done # 动态生成预期输出 number_width = len(str(item_count)) expected_lines = [] for i in range(item_count): expected_lines.append(f"{i+1:{number_width}} Item {i+1} (2022-04-25)") expected_lines.extend(["---", f"{item_count} item(s)"]) expected = "\n".join(expected_lines) self.assertPrinted(expected)
方法二:自定义Mock文件对象(更灵活)
如果想直接模拟readlines()返回的列表,避免拼接超长字符串,可以自定义一个简单的Mock文件类:
def test_large_list_with_custom_mock(self): item_count = 5000 # 生成模拟的行列表(每条带换行符,和真实文件读取的格式一致) mock_lines = [f"Task {i+1}\n" for i in range(item_count)] class MockFile: def readlines(self): return mock_lines def __enter__(self): return self def __exit__(self, *args): pass with patch("todo.open", return_value=MockFile()): Handler().list() # 生成预期输出 number_width = len(str(item_count)) expected = "\n".join([f"{i+1:{number_width}} Task {i+1}" for i in range(item_count)]) expected += f"\n---\n{item_count} item(s)" self.assertPrinted(expected)
核心优势
- 不用手动编写超长字符串,测试代码简洁易维护
- 可以灵活调整条目数量,轻松测试不同位数的编号对齐(1位、2位、3位等)
- 动态生成预期输出,避免手动编写大量重复内容出错
内容的提问来源于stack exchange,提问作者Alex Hoggett
相关产品推荐
相关产品推荐

