单元测试Mock Twilio API时触发TypeError:'list'对象不可调用
问题:Twilio API单元测试Mock时触发TypeError
我开发了通过Twilio API获取Flow系统信息的FlowChecker类,业务代码运行正常,但单元测试Mock API时触发错误。测试代码中先将mock_client.studio.v2.flows设为列表,后续调用mock_client.studio.v2.flows(mock_flow.sid)时抛出TypeError: 'list' object is not callable,已搜索相关问题未找到解决方案,请求帮助。
业务代码
from twilio.rest import Client class FlowChecker: def __init__(self, twilio_sid, twilio_auth_token): self.twilio_SID = twilio_sid self.twilio_auth_token = twilio_auth_token self.client = Client(self.twilio_SID, self.twilio_auth_token) self.calls = self.client.calls.list() self.flows = self.client.studio.v2.flows def get_active_executions(self): active_executions = [] for flow in self.flows.list(): executions = self.client.studio.v2.flows(flow.sid).executions.list() for execution in executions: if execution._properties['status'] != 'ended': active_executions.append({'flow_sid': flow.sid, 'execution': execution})
测试代码(原错误版本)
import unittest from unittest.mock import Mock, patch from flows.twilio_flows import FlowChecker class FlowCheckerTest(unittest.TestCase): @patch('flows.twilio_flows.Client') def test_get_active_flows(self, mock_client): flow_checker = FlowChecker('fake_sid', 'fake_auth_token') mock_call = Mock() mock_flow = Mock() mock_flow.sid = 0 mock_execution = Mock() mock_execution._properties = {'status': 'ended'} mock_client.calls.list().return_value = [mock_call] mock_client.studio.v2.flows = [mock_flow] mock_client.studio.v2.flows(mock_flow.sid).executions.list().return_value = [mock_execution] self.assertEqual(flow_checker.get_active_executions(), [])
错误栈
Ran 2 tests in 0.045s FAILED (errors=1) Error Traceback (most recent call last): File "C:\Users\Devon\AppData\Local\Programs\Python\Python310\lib\unittest\mock.py", line 1369, in patched return func(*newargs, **newkeywargs) File "C:\Users\Devon\PycharmProjects\Day_35\tests\twilio_flows_test'.py", line 19, in test_get_active_flows_when_empty mock_client.studio.v2.flows(mock_flow.sid).executions.list().return_value = [mock_execution] TypeError: 'list' object is not callable Process finished with exit code 1
错误分析
你将mock_client.studio.v2.flows直接赋值为列表[mock_flow],但Twilio的flows对象实际具备双重特性:既是可调用对象(通过flows(sid)获取单个flow),又拥有.list()方法获取flow列表。列表属于不可调用类型,执行flows(mock_flow.sid)时自然触发类型错误。
修正后的测试代码
import unittest from unittest.mock import Mock, patch from flows.twilio_flows import FlowChecker class FlowCheckerTest(unittest.TestCase): @patch('flows.twilio_flows.Client') def test_get_active_flows(self, mock_client): # 初始化模拟对象 mock_call = Mock() mock_flow = Mock() mock_flow.sid = 0 mock_execution = Mock() mock_execution._properties = {'status': 'ended'} # 配置calls的返回值 mock_client.calls.list.return_value = [mock_call] # 创建flows的Mock对象,同时支持调用和list方法 mock_flows = Mock() mock_flows.list.return_value = [mock_flow] # 配置flows(sid)返回的对象,包含executions属性 mock_single_flow = Mock() mock_single_flow.executions.list.return_value = [mock_execution] mock_flows.return_value = mock_single_flow # 将mock_flows赋值给client.studio.v2.flows mock_client.studio.v2.flows = mock_flows # 初始化FlowChecker并执行测试 flow_checker = FlowChecker('fake_sid', 'fake_auth_token') self.assertEqual(flow_checker.get_active_executions(), [])
关键修正点
- 用
Mock()创建mock_flows对象,替代直接赋值列表 - 给
mock_flows.list设置返回值,对应业务代码中self.flows.list()的调用 - 创建
mock_single_flow模拟单个flow对象,配置其executions.list的返回值,再让mock_flows()(调用时)返回这个对象,匹配业务代码中flows(flow.sid).executions.list()的逻辑
内容的提问来源于stack exchange,提问作者Devon Hume
相关产品推荐
相关产品推荐

