pytest_mock

 1from pytest_mock.plugin import AsyncMockType
 2from pytest_mock.plugin import MockerFixture
 3from pytest_mock.plugin import MockType
 4from pytest_mock.plugin import PytestMockWarning
 5from pytest_mock.plugin import class_mocker
 6from pytest_mock.plugin import mocker
 7from pytest_mock.plugin import module_mocker
 8from pytest_mock.plugin import package_mocker
 9from pytest_mock.plugin import pytest_addoption
10from pytest_mock.plugin import pytest_configure
11from pytest_mock.plugin import session_mocker
12
13MockFixture = MockerFixture  # backward-compatibility only (#204)
14
15__all__ = [
16    "AsyncMockType",
17    "MockerFixture",
18    "MockFixture",
19    "MockType",
20    "PytestMockWarning",
21    "pytest_addoption",
22    "pytest_configure",
23    "session_mocker",
24    "package_mocker",
25    "module_mocker",
26    "class_mocker",
27    "mocker",
28]
AsyncMockType = <class 'unittest.mock.AsyncMock'>
class MockerFixture:
 81class MockerFixture:
 82    """
 83    Fixture that provides the same interface to functions in the mock module,
 84    ensuring that they are uninstalled at the end of each test.
 85    """
 86
 87    def __init__(self, config: Any) -> None:
 88        self._mock_cache: MockCache = MockCache()
 89        self.mock_module = mock_module = get_mock_module(config)
 90        self.patch = self._Patcher(self._mock_cache, mock_module)  # type: MockerFixture._Patcher
 91        # aliases for convenience
 92        self.Mock = mock_module.Mock
 93        self.MagicMock = mock_module.MagicMock
 94        self.NonCallableMock = mock_module.NonCallableMock
 95        self.NonCallableMagicMock = mock_module.NonCallableMagicMock
 96        self.PropertyMock = mock_module.PropertyMock
 97        if hasattr(mock_module, "AsyncMock"):
 98            self.AsyncMock = mock_module.AsyncMock
 99        self.call = mock_module.call
100        self.ANY = mock_module.ANY
101        self.DEFAULT = mock_module.DEFAULT
102        self.sentinel = mock_module.sentinel
103        self.mock_open = mock_module.mock_open
104        if hasattr(mock_module, "seal"):
105            self.seal = mock_module.seal
106
107    def create_autospec(
108        self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
109    ) -> MockType:
110        m: MockType = self.mock_module.create_autospec(
111            spec, spec_set, instance, **kwargs
112        )
113        self._mock_cache.add(m)
114        return m
115
116    def resetall(
117        self, *, return_value: bool = False, side_effect: bool = False
118    ) -> None:
119        """
120        Call reset_mock() on all patchers started by this fixture.
121
122        :param bool return_value: Reset the return_value of mocks.
123        :param bool side_effect: Reset the side_effect of mocks.
124        """
125        supports_reset_mock_with_args: tuple[type[Any], ...]
126        if hasattr(self, "AsyncMock"):
127            supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
128        else:
129            supports_reset_mock_with_args = (self.Mock,)
130
131        for mock_item in self._mock_cache:
132            # See issue #237.
133            if not hasattr(mock_item.mock, "reset_mock"):
134                continue
135            # NOTE: The mock may be a dictionary
136            if hasattr(mock_item.mock, "spy_return_list"):
137                mock_item.mock.spy_return_list = []
138            if hasattr(mock_item.mock, "spy_return_iter"):
139                mock_item.mock.spy_return_iter = None
140            if isinstance(mock_item.mock, supports_reset_mock_with_args):
141                mock_item.mock.reset_mock(
142                    return_value=return_value, side_effect=side_effect
143                )
144            else:
145                mock_item.mock.reset_mock()
146
147    def stopall(self) -> None:
148        """
149        Stop all patchers started by this fixture. Can be safely called multiple
150        times.
151        """
152        self._mock_cache.clear()
153
154    def stop(self, mock: unittest.mock.MagicMock) -> None:
155        """
156        Stops a previous patch or spy call by passing the ``MagicMock`` object
157        returned by it.
158        """
159        self._mock_cache.remove(mock)
160
161    def spy(
162        self, obj: object, name: str, duplicate_iterators: bool = False
163    ) -> MockType:
164        """
165        Create a spy of method. It will run method normally, but it is now
166        possible to use `mock` call features with it, like call count.
167
168        :param obj: An object.
169        :param name: A method in object.
170        :param duplicate_iterators: Whether to keep a copy of the returned iterator in `spy_return_iter`.
171        :return: Spy object.
172        """
173        method = getattr(obj, name)
174
175        def wrapper(*args, **kwargs):
176            spy_obj.spy_return = None
177            spy_obj.spy_exception = None
178            try:
179                r = method(*args, **kwargs)
180            except BaseException as e:
181                spy_obj.spy_exception = e
182                raise
183            else:
184                if duplicate_iterators and isinstance(r, Iterator):
185                    r, duplicated_iterator = itertools.tee(r, 2)
186                    spy_obj.spy_return_iter = duplicated_iterator
187                else:
188                    spy_obj.spy_return_iter = None
189
190                spy_obj.spy_return = r
191                spy_obj.spy_return_list.append(r)
192            return r
193
194        async def async_wrapper(*args, **kwargs):
195            spy_obj.spy_return = None
196            spy_obj.spy_exception = None
197            try:
198                r = await method(*args, **kwargs)
199            except BaseException as e:
200                spy_obj.spy_exception = e
201                raise
202            else:
203                spy_obj.spy_return = r
204                spy_obj.spy_return_list.append(r)
205            return r
206
207        if inspect.iscoroutinefunction(method):
208            wrapped = functools.update_wrapper(async_wrapper, method)
209        else:
210            wrapped = functools.update_wrapper(wrapper, method)
211
212        autospec = inspect.ismethod(method) or inspect.isfunction(method)
213
214        spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
215        spy_obj.spy_return = None
216        spy_obj.spy_return_iter = None
217        spy_obj.spy_return_list = []
218        spy_obj.spy_exception = None
219        return spy_obj
220
221    def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
222        """
223        Create a stub method. It accepts any arguments. Ideal to register to
224        callbacks in tests.
225
226        :param name: the constructed stub's name as used in repr
227        :return: Stub object.
228        """
229        return cast(
230            unittest.mock.MagicMock,
231            self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
232        )
233
234    def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
235        """
236        Create a async stub method. It accepts any arguments. Ideal to register to
237        callbacks in tests.
238
239        :param name: the constructed stub's name as used in repr
240        :return: Stub object.
241        """
242        return cast(
243            AsyncMockType,
244            self.mock_module.AsyncMock(spec=lambda *args, **kwargs: None, name=name),
245        )
246
247    class _Patcher:
248        """
249        Object to provide the same interface as mock.patch, mock.patch.object,
250        etc. We need this indirection to keep the same API of the mock package.
251        """
252
253        DEFAULT = object()
254
255        def __init__(self, mock_cache, mock_module):
256            self.__mock_cache = mock_cache
257            self.mock_module = mock_module
258
259        def _start_patch(
260            self, mock_func: Any, warn_on_mock_enter: bool, *args: Any, **kwargs: Any
261        ) -> MockType:
262            """Patches something by calling the given function from the mock
263            module, registering the patch to stop it later and returns the
264            mock object resulting from the mock call.
265            """
266            p = mock_func(*args, **kwargs)
267            mocked: MockType = p.start()
268            self.__mock_cache.add(mock=mocked, patch=p)
269            if hasattr(mocked, "reset_mock"):
270                # check if `mocked` is actually a mock object, as depending on autospec or target
271                # parameters `mocked` can be anything
272                if hasattr(mocked, "__enter__") and warn_on_mock_enter:
273                    mocked.__enter__.side_effect = lambda: warnings.warn(
274                        "Mocks returned by pytest-mock do not need to be used as context managers. "
275                        "The mocker fixture automatically undoes mocking at the end of a test. "
276                        "This warning can be ignored if it was triggered by mocking a context manager. "
277                        "https://pytest-mock.readthedocs.io/en/latest/usage.html#usage-as-context-manager",
278                        PytestMockWarning,
279                        stacklevel=5,
280                    )
281            return mocked
282
283        def object(
284            self,
285            target: object,
286            attribute: str,
287            new: object = DEFAULT,
288            spec: Optional[object] = None,
289            create: bool = False,
290            spec_set: Optional[object] = None,
291            autospec: Optional[object] = None,
292            new_callable: object = None,
293            **kwargs: Any,
294        ) -> MockType:
295            """API to mock.patch.object"""
296            if new is self.DEFAULT:
297                new = self.mock_module.DEFAULT
298            return self._start_patch(
299                self.mock_module.patch.object,
300                True,
301                target,
302                attribute,
303                new=new,
304                spec=spec,
305                create=create,
306                spec_set=spec_set,
307                autospec=autospec,
308                new_callable=new_callable,
309                **kwargs,
310            )
311
312        def context_manager(
313            self,
314            target: builtins.object,
315            attribute: str,
316            new: builtins.object = DEFAULT,
317            spec: Optional[builtins.object] = None,
318            create: bool = False,
319            spec_set: Optional[builtins.object] = None,
320            autospec: Optional[builtins.object] = None,
321            new_callable: builtins.object = None,
322            **kwargs: Any,
323        ) -> MockType:
324            """This is equivalent to mock.patch.object except that the returned mock
325            does not issue a warning when used as a context manager."""
326            if new is self.DEFAULT:
327                new = self.mock_module.DEFAULT
328            return self._start_patch(
329                self.mock_module.patch.object,
330                False,
331                target,
332                attribute,
333                new=new,
334                spec=spec,
335                create=create,
336                spec_set=spec_set,
337                autospec=autospec,
338                new_callable=new_callable,
339                **kwargs,
340            )
341
342        def multiple(
343            self,
344            target: builtins.object,
345            spec: Optional[builtins.object] = None,
346            create: bool = False,
347            spec_set: Optional[builtins.object] = None,
348            autospec: Optional[builtins.object] = None,
349            new_callable: Optional[builtins.object] = None,
350            **kwargs: Any,
351        ) -> dict[str, MockType]:
352            """API to mock.patch.multiple"""
353            return self._start_patch(
354                self.mock_module.patch.multiple,
355                True,
356                target,
357                spec=spec,
358                create=create,
359                spec_set=spec_set,
360                autospec=autospec,
361                new_callable=new_callable,
362                **kwargs,
363            )
364
365        def dict(
366            self,
367            in_dict: Union[Mapping[Any, Any], str],
368            values: Union[Mapping[Any, Any], Iterable[tuple[Any, Any]]] = (),
369            clear: bool = False,
370            **kwargs: Any,
371        ) -> Any:
372            """API to mock.patch.dict"""
373            return self._start_patch(
374                self.mock_module.patch.dict,
375                True,
376                in_dict,
377                values=values,
378                clear=clear,
379                **kwargs,
380            )
381
382        @overload
383        def __call__(
384            self,
385            target: str,
386            new: None = ...,
387            spec: Optional[builtins.object] = ...,
388            create: bool = ...,
389            spec_set: Optional[builtins.object] = ...,
390            autospec: Optional[builtins.object] = ...,
391            new_callable: None = ...,
392            **kwargs: Any,
393        ) -> MockType: ...
394
395        @overload
396        def __call__(
397            self,
398            target: str,
399            new: _T,
400            spec: Optional[builtins.object] = ...,
401            create: bool = ...,
402            spec_set: Optional[builtins.object] = ...,
403            autospec: Optional[builtins.object] = ...,
404            new_callable: None = ...,
405            **kwargs: Any,
406        ) -> _T: ...
407
408        @overload
409        def __call__(
410            self,
411            target: str,
412            new: None,
413            spec: Optional[builtins.object],
414            create: bool,
415            spec_set: Optional[builtins.object],
416            autospec: Optional[builtins.object],
417            new_callable: Callable[[], _T],
418            **kwargs: Any,
419        ) -> _T: ...
420
421        @overload
422        def __call__(
423            self,
424            target: str,
425            new: None = ...,
426            spec: Optional[builtins.object] = ...,
427            create: bool = ...,
428            spec_set: Optional[builtins.object] = ...,
429            autospec: Optional[builtins.object] = ...,
430            *,
431            new_callable: Callable[[], _T],
432            **kwargs: Any,
433        ) -> _T: ...
434
435        def __call__(
436            self,
437            target: str,
438            new: builtins.object = DEFAULT,
439            spec: Optional[builtins.object] = None,
440            create: bool = False,
441            spec_set: Optional[builtins.object] = None,
442            autospec: Optional[builtins.object] = None,
443            new_callable: Optional[Callable[[], Any]] = None,
444            **kwargs: Any,
445        ) -> Any:
446            """API to mock.patch"""
447            if new is self.DEFAULT:
448                new = self.mock_module.DEFAULT
449            return self._start_patch(
450                self.mock_module.patch,
451                True,
452                target,
453                new=new,
454                spec=spec,
455                create=create,
456                spec_set=spec_set,
457                autospec=autospec,
458                new_callable=new_callable,
459                **kwargs,
460            )

Fixture that provides the same interface to functions in the mock module, ensuring that they are uninstalled at the end of each test.

MockerFixture(config: Any)
 87    def __init__(self, config: Any) -> None:
 88        self._mock_cache: MockCache = MockCache()
 89        self.mock_module = mock_module = get_mock_module(config)
 90        self.patch = self._Patcher(self._mock_cache, mock_module)  # type: MockerFixture._Patcher
 91        # aliases for convenience
 92        self.Mock = mock_module.Mock
 93        self.MagicMock = mock_module.MagicMock
 94        self.NonCallableMock = mock_module.NonCallableMock
 95        self.NonCallableMagicMock = mock_module.NonCallableMagicMock
 96        self.PropertyMock = mock_module.PropertyMock
 97        if hasattr(mock_module, "AsyncMock"):
 98            self.AsyncMock = mock_module.AsyncMock
 99        self.call = mock_module.call
100        self.ANY = mock_module.ANY
101        self.DEFAULT = mock_module.DEFAULT
102        self.sentinel = mock_module.sentinel
103        self.mock_open = mock_module.mock_open
104        if hasattr(mock_module, "seal"):
105            self.seal = mock_module.seal
patch
Mock
MagicMock
NonCallableMock
NonCallableMagicMock
PropertyMock
call
ANY
DEFAULT
sentinel
mock_open
def create_autospec( self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any) -> Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]:
107    def create_autospec(
108        self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
109    ) -> MockType:
110        m: MockType = self.mock_module.create_autospec(
111            spec, spec_set, instance, **kwargs
112        )
113        self._mock_cache.add(m)
114        return m
def resetall(self, *, return_value: bool = False, side_effect: bool = False) -> None:
116    def resetall(
117        self, *, return_value: bool = False, side_effect: bool = False
118    ) -> None:
119        """
120        Call reset_mock() on all patchers started by this fixture.
121
122        :param bool return_value: Reset the return_value of mocks.
123        :param bool side_effect: Reset the side_effect of mocks.
124        """
125        supports_reset_mock_with_args: tuple[type[Any], ...]
126        if hasattr(self, "AsyncMock"):
127            supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
128        else:
129            supports_reset_mock_with_args = (self.Mock,)
130
131        for mock_item in self._mock_cache:
132            # See issue #237.
133            if not hasattr(mock_item.mock, "reset_mock"):
134                continue
135            # NOTE: The mock may be a dictionary
136            if hasattr(mock_item.mock, "spy_return_list"):
137                mock_item.mock.spy_return_list = []
138            if hasattr(mock_item.mock, "spy_return_iter"):
139                mock_item.mock.spy_return_iter = None
140            if isinstance(mock_item.mock, supports_reset_mock_with_args):
141                mock_item.mock.reset_mock(
142                    return_value=return_value, side_effect=side_effect
143                )
144            else:
145                mock_item.mock.reset_mock()

Call reset_mock() on all patchers started by this fixture.

Parameters
  • bool return_value: Reset the return_value of mocks.
  • bool side_effect: Reset the side_effect of mocks.
def stopall(self) -> None:
147    def stopall(self) -> None:
148        """
149        Stop all patchers started by this fixture. Can be safely called multiple
150        times.
151        """
152        self._mock_cache.clear()

Stop all patchers started by this fixture. Can be safely called multiple times.

def stop(self, mock: unittest.mock.MagicMock) -> None:
154    def stop(self, mock: unittest.mock.MagicMock) -> None:
155        """
156        Stops a previous patch or spy call by passing the ``MagicMock`` object
157        returned by it.
158        """
159        self._mock_cache.remove(mock)

Stops a previous patch or spy call by passing the MagicMock object returned by it.

def spy( self, obj: object, name: str, duplicate_iterators: bool = False) -> Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]:
161    def spy(
162        self, obj: object, name: str, duplicate_iterators: bool = False
163    ) -> MockType:
164        """
165        Create a spy of method. It will run method normally, but it is now
166        possible to use `mock` call features with it, like call count.
167
168        :param obj: An object.
169        :param name: A method in object.
170        :param duplicate_iterators: Whether to keep a copy of the returned iterator in `spy_return_iter`.
171        :return: Spy object.
172        """
173        method = getattr(obj, name)
174
175        def wrapper(*args, **kwargs):
176            spy_obj.spy_return = None
177            spy_obj.spy_exception = None
178            try:
179                r = method(*args, **kwargs)
180            except BaseException as e:
181                spy_obj.spy_exception = e
182                raise
183            else:
184                if duplicate_iterators and isinstance(r, Iterator):
185                    r, duplicated_iterator = itertools.tee(r, 2)
186                    spy_obj.spy_return_iter = duplicated_iterator
187                else:
188                    spy_obj.spy_return_iter = None
189
190                spy_obj.spy_return = r
191                spy_obj.spy_return_list.append(r)
192            return r
193
194        async def async_wrapper(*args, **kwargs):
195            spy_obj.spy_return = None
196            spy_obj.spy_exception = None
197            try:
198                r = await method(*args, **kwargs)
199            except BaseException as e:
200                spy_obj.spy_exception = e
201                raise
202            else:
203                spy_obj.spy_return = r
204                spy_obj.spy_return_list.append(r)
205            return r
206
207        if inspect.iscoroutinefunction(method):
208            wrapped = functools.update_wrapper(async_wrapper, method)
209        else:
210            wrapped = functools.update_wrapper(wrapper, method)
211
212        autospec = inspect.ismethod(method) or inspect.isfunction(method)
213
214        spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
215        spy_obj.spy_return = None
216        spy_obj.spy_return_iter = None
217        spy_obj.spy_return_list = []
218        spy_obj.spy_exception = None
219        return spy_obj

Create a spy of method. It will run method normally, but it is now possible to use mock call features with it, like call count.

Parameters
  • obj: An object.
  • name: A method in object.
  • duplicate_iterators: Whether to keep a copy of the returned iterator in spy_return_iter.
Returns

Spy object.

def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
221    def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
222        """
223        Create a stub method. It accepts any arguments. Ideal to register to
224        callbacks in tests.
225
226        :param name: the constructed stub's name as used in repr
227        :return: Stub object.
228        """
229        return cast(
230            unittest.mock.MagicMock,
231            self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
232        )

Create a stub method. It accepts any arguments. Ideal to register to callbacks in tests.

Parameters
  • name: the constructed stub's name as used in repr
Returns

Stub object.

def async_stub(self, name: Optional[str] = None) -> unittest.mock.AsyncMock:
234    def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
235        """
236        Create a async stub method. It accepts any arguments. Ideal to register to
237        callbacks in tests.
238
239        :param name: the constructed stub's name as used in repr
240        :return: Stub object.
241        """
242        return cast(
243            AsyncMockType,
244            self.mock_module.AsyncMock(spec=lambda *args, **kwargs: None, name=name),
245        )

Create a async stub method. It accepts any arguments. Ideal to register to callbacks in tests.

Parameters
  • name: the constructed stub's name as used in repr
Returns

Stub object.

MockFixture = <class 'MockerFixture'>
MockType = typing.Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]
class PytestMockWarning(builtins.UserWarning):
37class PytestMockWarning(UserWarning):
38    """Base class for all warnings emitted by pytest-mock."""

Base class for all warnings emitted by pytest-mock.

def pytest_addoption(parser: Any) -> None:
705def pytest_addoption(parser: Any) -> None:
706    parser.addini(
707        "mock_traceback_monkeypatch",
708        "Monkeypatch the mock library to improve reporting of the "
709        "assert_called_... methods",
710        default=True,
711    )
712    parser.addini(
713        "mock_use_standalone_module",
714        'Use standalone "mock" (from PyPI) instead of builtin "unittest.mock" '
715        "on Python 3",
716        default=False,
717    )
def pytest_configure(config: Any) -> None:
720def pytest_configure(config: Any) -> None:
721    tb = config.getoption("--tb", default="auto")
722    if (
723        parse_ini_boolean(config.getini("mock_traceback_monkeypatch"))
724        and tb != "native"
725    ):
726        wrap_assert_methods(config)
def session_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def package_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def module_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def class_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.