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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:57:03