Python 单元测试断言尝试将模拟与字符串进行比较失败

问题描述 投票:0回答:1

我正在尝试学习如何使用 pytest 和模拟进行单元测试。我有一个非常简单的用例:

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

正如你所看到的,我正在尝试模拟对

self._simple_sf_client.bulk2.Account.download
的链式调用,但是
assert client.bulk2('query', 'path', 1) == '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) == '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

我一定在这里遗漏了一些明显的东西。为什么它不返回我在配置模拟时设置的值?谢谢

python unit-testing mocking
1个回答
0
投票

看起来您正确配置了模拟,但问题在于断言中的比较。

assert
语句正在将
client.bulk2('query', 'path', 1)
的返回值与字符串“test”进行比较,但返回值是一个模拟对象,而不是字符串“test”。

要解决此问题,您需要访问模拟对象的返回值。在你的例子中,模拟对象代表方法

bulk2.Account.download
。您可以使用模拟的
return_value
属性访问返回值。这是更正的断言:

assert client.bulk2('query', 'path', 1).return_value == 'test'

这会将模拟的返回值(设置为“test”)与字符串“test”进行比较。相应地更新测试函数中的断言,它应该按预期工作。

这是修改后的测试函数:

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'

此更改应该可以解决您遇到的 AssertionError。

© www.soinside.com 2019 - 2024. All rights reserved.