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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:45:30