Python unittest调用方法返回MagicMock而非tuple返回值如何解决
问题原因
- 核心错误:你通过
@mock.patch('path.A.create_sources')把待测试的目标方法直接替换成了Mock对象,调用时完全不会走你写的真实业务逻辑,自然返回MagicMock而非预期元组。 - 方法调用错误:首先你类中定义的方法名是
create_sources,测试代码里误写为create_new_sources;其次create_sources是实例方法,你直接调用类A的方法而非fixture生成的A类实例a_cs,调用方式本身不符合语法规范。 - 业务代码存在语法和逻辑错误:
new_sources = self.get_new_sources() -> ['x','y']是非法语法,类型注解不能写在方法调用语句后,运行会直接报错requests.post相关逻辑缩进在for循环外,只会在遍历完所有待创建资源后发送一次请求,且最终只会把最后一个资源加入成功/失败列表,业务逻辑本身存在问题
- mock对象选择错误:你应该mock的是
create_sources依赖的外部资源(get_new_sources方法、requests.post方法),而非要测试的业务方法本身。
修正方案
第一步:修正业务代码
import requests class A(): def __init__(self, config): self.config = config self.auth_token = config.auth_token def create_sources(self): successful = [] unsuccessful = [] new_sources = self.get_new_sources() if len(new_sources): for source in new_sources: req = { # 实际业务的JSON参数 } # post逻辑移到for循环内部 response = requests.post( self.config.base_url, headers={"Authorization": self.auth_token}, json=req ) if response.status_code == 200: successful.append(source) else: unsuccessful.append(source) print(f"Successful: {successful}; Unsuccessful: {unsuccessful}") return (successful, unsuccessful)
第二步:修正测试代码
import pytest from unittest import mock @pytest.fixture def a_config(): a_config = Mock(spec=AConfig) a_config.base_url = "https://example.com" a_config.auth_token = "abcdefg" return a_config @pytest.fixture def a_cs(a_config): return A(a_config) class TestA(object): # 仅mock依赖的外部请求方法,不mock待测试的业务方法 @mock.patch('path.to.your.business.code.requests.post') def test_create_new_sources_success(self, mock_post, a_cs): # 模拟请求返回成功状态 mock_post.return_value.status_code = 200 # 模拟获取待创建资源的返回值 a_cs.get_new_sources = Mock(return_value=['test']) # 调用实例的待测试方法 successful_unsuccessful = a_cs.create_sources() assert len(successful_unsuccessful[0]) == 1 assert len(successful_unsuccessful[1]) == 0
内容的提问来源于stack exchange,提问作者NAB0815
相关产品推荐
相关产品推荐

