gpt4 book ai didi

python - patch.multiple 是否与 pytest 作为装饰器一起使用

转载 作者:行者123 更新时间:2023-12-03 23:44:58 24 4
gpt4 key购买 nike

我有一个 test_tmp.py来自https://docs.python.org/3/library/unittest.mock.html#patch-multiple

from unittest.mock import DEFAULT, MagicMock, patch

thing = object()
other = object()

@patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
def test_function(thing, other):
print(f'thing={thing}')
print(f'other={other}')
assert isinstance(thing, MagicMock)
assert isinstance(other, MagicMock)

test_function()
它与python一起运行
python test_tmp.py
thing=<MagicMock name='thing' id='4355085552'>
other=<MagicMock name='other' id='4355243312'>
但它不适用于 pytest,错误如下
pytest test_tmp.py
============================================================================================================= test session starts =============================================================================================================
platform darwin -- Python 3.8.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /private/tmp
collected 0 items / 1 error

=================================================================================================================== ERRORS ====================================================================================================================
________________________________________________________________________________________________________ ERROR collecting test_tmp.py _________________________________________________________________________________________________________
test_tmp.py:13: in <module>
test_function()
/Users/user/.pyenv/versions/3.8.2/lib/python3.8/unittest/mock.py:1345: in patched
with self.decoration_helper(patched,
/Users/user/.pyenv/versions/3.8.2/lib/python3.8/contextlib.py:113: in __enter__
return next(self.gen)
/Users/user/.pyenv/versions/3.8.2/lib/python3.8/unittest/mock.py:1313: in decoration_helper
arg = patching.__enter__()
/Users/user/.pyenv/versions/3.8.2/lib/python3.8/unittest/mock.py:1416: in __enter__
original, local = self.get_original()
/Users/user/.pyenv/versions/3.8.2/lib/python3.8/unittest/mock.py:1389: in get_original
raise AttributeError(
E AttributeError: <module '__main__' from '/path/to/bin/pytest'> does not have the attribute 'thing'
=========================================================================================================== short test summary info ===========================================================================================================
ERROR test_tmp.py - AttributeError: <module '__main__' from '/path/to/bin/pytest'> does not have the attribute 'thing'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================================================== 1 error in 0.31s ===============================================================================================================
想知道为什么?
我正在使用 pytest = "^5.4.3"

最佳答案

这里有一些东西在 pytest 中不起作用:

  • 您不能直接调用测试,因此调用该函数将不起作用
  • 装饰器版本在这种情况下不起作用,我猜 pytest 只是没有实现这一点(pytest 默认将测试函数参数理解为 fixture ;它正确处理 patchpatch.object 使用的位置参数,但似乎无法处理patch.multiple 注入(inject)的关键字参数)
  • 使用 '__main__' 可能不起作用,您可以使用 sys.modules[__name__] 代替。

  • 所以这是一个工作版本:
    def test_function1():
    with patch.multiple(sys.modules[__name__],
    thing=DEFAULT,
    other=DEFAULT) as mocks:
    print(f'thing = {mocks["thing"]}')
    print(f'other = {mocks["other"]}')
    assert isinstance(thing, MagicMock)
    assert isinstance(other, MagicMock)
    此版本也应与 unittest 一起使用。
    在 pytest 中,您通常会将这种模拟移动到一个 fixture 中,所以这可能更符合 pytest 的精神:
    @pytest.fixture
    def multiple():
    with patch.multiple(sys.modules[__name__],
    thing=DEFAULT,
    other=DEFAULT) as mocks:
    yield mocks


    def test_function(multiple):
    print(f'thing = {multiple["thing"]}')
    print(f'other = {multiple["other"]}')
    assert isinstance(thing, MagicMock)
    assert isinstance(other, MagicMock)
    笔记:
    这确实只回答了标题中的问题,而不是“为什么” - 我查看了 patch.multiple 的源代码,但不明白它如何与 pytest 交互。也许有更深入的人可以回答这个问题。

    关于python - patch.multiple 是否与 pytest 作为装饰器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63401314/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com