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

Pytest Mock链式调用断言失败:Mock对象与字符串对比错误

问题:unittest.mock链式调用Mock返回值不生效

测试场景代码

from simple_salesforce import Salesforce
from unittest.mock import Mock

class SFClient:
    def __init__(self, sf_client: Salesforce):
        self._simple_sf_client = sf_client

    def bulk2(self, query: str, path: str, max_records: int) -> list[dict]:
        return self._simple_sf_client.bulk2.Account.download(
            query=query, path=path, max_records=max_records
        )


def test_client_bulk2():
    mock_sf = Mock()
    config = {'bulk2.return_value.Account.return_value.download.return_value': 'test'}
    mock_sf.configure_mock(**config)
    client = SFClient(sf_client=mock_sf)
    assert client.bulk2('query', 'path', 1) == 'test'
    assert False

错误日志

运行pytest后报错:

$ poetry run pytest
F                                                                                                                                                                                                                                                                                                                [100%]
======================================================================================================================================================= FAILURES =======================================================================================================================================================
__________________________________________________________________________________________________________________________________________________ test_client_bulk2 ___________________________________________________________________________________________________________________________________________________

    def test_client_bulk2():
        mock_sf = Mock()
        config = {'bulk2.return_value.Account.return_value.download.return_value': 'test'}
        mock_sf.configure_mock(**config)
        client = SFClient(sf_client=mock_sf)
>       assert client.bulk2('query', 'path', 1) == 'test'
E       AssertionError: assert <Mock name='mock.bulk2.Account.download()' id='140589080832208'> == 'test'
E        +  where <Mock name='mock.bulk2.Account.download()' id='140589080832208'> = <bound method SFClient.bulk2 of <tests.test_salesforce.SFClient object at 0x7fdd73acdd90>>('query', 'path', 1)
E        +    where <bound method SFClient.bulk2 of <tests.test_salesforce.SFClient object at 0x7fdd73acdd90>> = <tests.test_salesforce.SFClient object at 0x7fdd73acdd90>.bulk2

tests/test_salesforce.py:27: AssertionError
=================================================================================================================================================== warnings summary ===================================================================================================================================================
../../.cache/pypoetry/virtualenvs/salesforce-archivist-n3oqdCBe-py3.11/lib/python3.11/site-packages/zeep/utils.py:1
  /home/piotrek/.cache/pypoetry/virtualenvs/salesforce-archivist-n3oqdCBe-py3.11/lib/python3.11/site-packages/zeep/utils.py:1: DeprecationWarning: 'cgi' is deprecated and slated for removal in Python 3.13
    import cgi

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=============================================================================================================================================== short test summary info ================================================================================================================================================
FAILED tests/test_salesforce.py::test_client_bulk2 - AssertionError: assert <Mock name='mock.bulk2.Account.download()' id='140589080832208'> == 'test'
1 failed, 1 warning in 0.19s

编辑后的尝试

尝试修改断言为assert client.bulk2('query', 'path', 1).return_value == 'test',仍然失败:

$ poetry run pytest
F                                                                                                                                                                                                                                                                                                                [100%]
======================================================================================================================================================= FAILURES =======================================================================================================================================================
__________________________________________________________________________________________________________________________________________________ test_client_bulk2 ___________________________________________________________________________________________________________________________________________________

    def test_client_bulk2():
        mock_sf = Mock()
        config = {'bulk2.return_value.Account.return_value.download.return_value': 'test'}
        mock_sf.configure_mock(**config)
        client = SFClient(sf_client=mock_sf)
>       assert client.bulk2('query', 'path', 1).return_value == 'test'
E       AssertionError: assert <Mock name='mock.bulk2.Account.download()()' id='140508290106704'> == 'test'
E        +  where <Mock name='mock.bulk2.Account.download()()' id='140508290106704'> = <Mock name='mock.bulk2.Account.download()' id='140508282777104'>.return_value
E        +    where <Mock name='mock.bulk2.Account.download()' id='140508282777104'> = <bound method SFClient.bulk2 of <tests.test_salesforce.SFClient object at 0x7fcaa2b95150>>('query', 'path', 1)
E        +      where <bound method SFClient.bulk2 of <tests.test_salesforce.SFClient object at 0x7fcaa2b95150>> = <tests.test_salesforce.SFClient object at 0x7fcaa2b95150>.bulk2

tests/test_salesforce.py:27: AssertionError
=================================================================================================================================================== warnings summary ===================================================================================================================================================
../../.cache/pypoetry/virtualenvs/salesforce-archivist-n3oqdCBe-py3.11/lib/python3.11/site-packages/zeep/utils.py:1
  /home/piotrek/.cache/pypoetry/virtualenvs/salesforce-archivist-n3oqdCBe-py3.11/lib/python3.11/site-packages/zeep/utils.py:1: DeprecationWarning: 'cgi' is deprecated and slated for removal in Python 3.13
    import cgi

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=============================================================================================================================================== short test summary info ================================================================================================================================================
FAILED tests/test_salesforce.py::test_client_bulk2 - AssertionError: assert <Mock name='mock.bulk2.Account.download()()' id='140508290106704'> == 'test'
1 failed, 1 warning in 0.19s

原因与解决方案

问题根源

原代码中self._simple_sf_client.bulk2是直接访问属性(没有调用方法,即无bulk2()),但配置mock时错误地给bulk2添加了.return_value,导致mock结构与实际调用链不匹配。

实际调用链是:mock_sf.bulk2.Account.download(...),而你的配置是给mock_sf.bulk2()(方法调用)的返回值设置了Account属性,和实际调用的mock_sf.bulk2属性完全不是同一个对象。

修正后的测试代码

将mock配置中的bulk2.return_value改为bulk2,去掉多余的.return_value:

def test_client_bulk2():
    mock_sf = Mock()
    # 修正配置:去掉bulk2后的.return_value
    config = {'bulk2.Account.download.return_value': 'test'}
    mock_sf.configure_mock(**config)
    client = SFClient(sf_client=mock_sf)
    assert client.bulk2('query', 'path', 1) == 'test'
    # 删除assert False,让测试正常通过

验证

修改后运行pytest,断言会成功通过,因为现在mock的结构与实际调用链完全匹配:mock_sf.bulk2是一个Mock对象,它的Account属性的download方法返回值被设置为'test',和原代码的调用逻辑一致。

内容的提问来源于stack exchange,提问作者piotrekkr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:25:23