Python模拟CSV场景下用户输入并测试add_new_customer方法时遇StopIteration错误求助
Python模拟CSV场景下用户输入并测试add_new_customer方法时遇StopIteration错误求助
看起来你在测试NewCoustumer类的add_new_customer方法时碰到了StopIteration错误,我来帮你拆解问题并给出修复方案~
错误原因分析
你的测试代码里有个容易踩的小坑:
user_input = ['dan', 'sam','dan123'] @patch('builtins.input', side_effect=[user_input])
这里你把已经是列表的user_input又嵌套进了另一个列表里。side_effect接收列表时,会在每次调用被mock的方法(也就是input())时依次取出列表中的元素。你现在传的是[['dan', 'sam','dan123']],第一次调用input()会拿到整个列表['dan', 'sam','dan123'],但add_new_customer里需要连续调用3次input(),第二次调用时mock就没有剩余元素可以返回了,直接抛出StopIteration。
另外还有个测试规范问题:你的测试类AddCustomer同时继承了unittest.TestCase和NewCoustumer,这不是正确的测试写法,应该在测试方法里实例化NewCoustumer对象,而且最好模拟掉和文件操作相关的方法,避免测试时真的创建/修改本地的bank_data.csv。
修复后的测试代码
下面是修正后的main_test.py,同时还模拟了文件相关操作,让测试完全脱离真实文件,不会污染本地环境:
import unittest from unittest.mock import patch, Mock from main import NewCoustumer class AddCustomer(unittest.TestCase): def test_add_new_customer(self): user_input = ['dan', 'sam','dan123'] # 1. 模拟三次input输入,直接传user_input给side_effect with patch('builtins.input', side_effect=user_input): # 2. 实例化业务类对象 customer = NewCoustumer() # 3. 模拟generate_account_id方法,固定返回测试用的账号ID,避免依赖文件 with patch.object(customer, 'generate_account_id', return_value='10001'): # 4. 模拟CSV写入操作,完全避免实际读写本地文件 with patch('csv.writer') as mock_writer: mock_file = Mock() mock_file.__enter__.return_value = mock_file with patch('builtins.open', return_value=mock_file): result = customer.add_new_customer() # 验证方法返回值正确 self.assertTrue(result) # 额外验证:确认writerow被调用,且参数符合预期 mock_writer_instance = mock_writer.return_value mock_writer_instance.writerow.assert_called_once_with( ['10001', 'dan', 'sam', 'dan123', 0.0, 0.0] ) if __name__ == '__main__': unittest.main(verbosity=2 )
关键修改点说明
- 修正input的mock方式:直接把
user_input传给side_effect,这样三次input()调用会依次拿到'dan'、'sam'、'dan123',彻底解决StopIteration。 - 调整测试类写法:测试类只继承
unittest.TestCase,在方法内创建业务类实例,符合单元测试的隔离原则。 - 隔离文件操作:通过
patch.object模拟generate_account_id的返回值,用patch('csv.writer')和patch('builtins.open')完全模拟文件读写,测试过程不会修改本地的bank_data.csv。 - 增强测试验证:除了验证返回值为
True,还断言了writerow的调用参数,确保方法的业务逻辑完全符合预期。
快速简化版(临时测试用)
如果你只是想先快速解决错误验证方法逻辑,可以用这个简化版(但会实际修改本地CSV文件,适合临时调试):
import unittest from unittest.mock import patch from main import NewCoustumer class AddCustomer(unittest.TestCase): def test_add(self): user_input = ['dan', 'sam','dan123'] # 核心修正:直接传user_input给side_effect with patch('builtins.input', side_effect=user_input): customer = NewCoustumer() # 模拟账号生成方法,避免依赖已有文件内容 with patch.object(customer, 'generate_account_id', return_value='10001'): result = customer.add_new_customer() self.assertTrue(result) if __name__ == '__main__': unittest.main(verbosity=2 )
备注:内容来源于stack exchange,提问作者aisha bjn
相关产品推荐
相关产品推荐

