mocker.path create=False argument not working as stated?
noklam opened this issue · 3 comments
Minimal Example
import pytest
class Dummy:
def __init__(self, x) -> None:
self.x = x
@pytest.fixture
def mocker_create_true(mocker):
return mocker.patch(f"{__name__}.Dummy", create=True)
@pytest.fixture
def mocker_create_false(mocker):
return mocker.patch(f"{__name__}.Dummy", create=False)
def test_mocker_non_exist_attrs_true(mocker_create_true):
dummy = Dummy(1)
print(type(dummy), dummy)
dummy.p
def test_mocker_non_exist_attrs_false(mocker_create_false):
dummy = Dummy(1)
with pytest.raises(Exception):
print(type(dummy), dummy)
dummy.p
Expected Result
According to the documentation https://docs.python.org/3/library/unittest.mock.html#patch, non-exist attributes access should throw an error when mocker.patch(create=False)
is used.
Test Result
================================================================================================ FAILURES =================================================================================================
____________________________________________________________________________________ test_mocker_non_exist_attrs_false ____________________________________________________________________________________
mocker_create_false = <MagicMock name='Dummy' id='140519123293424'>
def test_mocker_non_exist_attrs_false(mocker_create_false):
dummy = Dummy(1)
with pytest.raises(Exception):
print(type(dummy), dummy)
> dummy.p
E Failed: DID NOT RAISE <class 'Exception'>
dummy/tests/test_dummy.py:28: Failed
------------------------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------------------------
<class 'unittest.mock.MagicMock'> <MagicMock name='Dummy()' id='140519123314000'>
========================================================================================= short test summary info =========================================================================================
FAILED dummy/tests/test_dummy.py::test_mocker_non_exist_attrs_false - Failed: DID NOT RAISE <class 'Exception'>
- a detailed description of the bug or problem you are having
- output of
pip list
from the virtual environment you are using - pytest and operating system versions
- minimal example if possible
Versions
pytest 6.2.5
pytest-cov 3.0.0
pytest-forked 1.4.0
pytest-mock 1.13.0
pytest-xdist 2.2.1
Python: 3.8.3 + MacOS
Hi,
Your mocker_create_true
is passing create=False
, is that a copy/paste error?
Can you check if you get a different behavior if you don't use the mocker
fixture, but user unittest.mock
directly?
If they behave the same, then it is not a bug, but if they differ, then we should look into it.
@nicoddemus
Thanks, it was a typo, but the failing test is the false one so it is still valid (I have updated the issue now).
I get the same error with unittest.mock.patch
, hopefully I am doing it right.
import pytest
from unittest.mock import patch
class Dummy:
def __init__(self, x) -> None:
self.x = x
@patch(f"{__name__}.Dummy", create=True)
def test_mocker_non_exist_attrs_true(mock_class):
dummy = mock_class(1)
print(__name__)
print(type(dummy), dummy)
dummy.p
@patch(f"{__name__}.Dummy", create=False)
def test_mocker_non_exist_attrs_false(mock_class):
dummy = mock_class(1)
with pytest.raises(Exception):
print(type(dummy), dummy)
dummy.p
------------------------------------------ Captured stdout call -------------------------------------------
<class 'unittest.mock.MagicMock'> <MagicMock name='Dummy()' id='140671590231248'>
========================================= short test summary info =========================================
FAILED dummy/tests/test_dummy.py::test_mocker_non_exist_attrs_false - Failed: DID NOT RAISE <class 'Exce...
If it works the same as unittest.mock
then it is working as intended.
I'm not sure create
will work as you want, it is meant to create a method if that method doesn't exist, but you are patching the entire class, which does exist (so create
has no effect).
I suggest to try autospec=True
, but I'm not sure that will work for attributes created during __init__
.
Closing for now as this is not related to pytest-mock, but feel free to follow with further questions. 👍