为何unittest中元素存在于列表却返回ValueError(not in list)?
我有一个removeAccountFromBank函数,用于在Bank类的账户列表中查找指定Account对象,找到则将其替换为None,未找到则直接返回。该函数在IDLE中运行完全正常,但对应的unittest测试却持续返回ValueError: <Mock id='2350965017280'> is not in list.。
函数代码
def removeAccountFromBank(self, account): target_index = accounts.index(account) accounts[target_index] = None return
测试代码(使用unittest)
def test_removeAccountFromBank(self): account = Mock() bank = Bank() accounts = [None, (account), None] print(accounts) bank.removeAccountFromBank(account) self.assertEqual(bank.get_accounts(), [None, None, None])
问题现象
预期测试能通过,但实际结果是:打印语句正确显示列表包含该Mock对象[None, <Mock id='2350965017280'>, None],但函数调用index方法时却触发错误:in removeAccountFromBank target_index = accounts.index(account) ValueError: <Mock id='2350965017280'> is not in list。单独测试accounts.index(account)时能得到正确索引1,但在unittest中报错。
原因分析
核心问题是测试代码里定义的accounts局部变量,和Bank类removeAccountFromBank方法操作的accounts列表不是同一个对象:
- 你在测试函数里创建的是局部
accounts列表,和Bank实例内部维护的账户列表毫无关联; - 同时,函数里直接使用全局的
accounts变量而非Bank实例的属性,进一步导致操作的不是目标列表。
解决方案
1. 修正Bank类的函数,操作实例属性而非全局变量
将函数里的全局accounts改为实例属性self.accounts,确保操作的是当前Bank实例的账户列表:
def removeAccountFromBank(self, account): target_index = self.accounts.index(account) self.accounts[target_index] = None return
2. 修改测试代码,初始化Bank实例的账户列表
不要在测试函数里定义局部accounts,而是直接初始化Bank实例的账户属性:
def test_removeAccountFromBank(self): account = Mock() bank = Bank() # 初始化Bank实例的账户列表 bank.accounts = [None, account, None] print(bank.accounts) bank.removeAccountFromBank(account) self.assertEqual(bank.get_accounts(), [None, None, None])
如果Bank类提供了设置账户的接口(比如set_accounts方法),也可以用接口来初始化,比直接赋值属性更规范。
内容的提问来源于stack exchange,提问作者Marshmallow

