pax_global_header00006660000000000000000000000064134643727510014526gustar00rootroot0000000000000052 comment=e0180b98d0e07e895a3f699b7e9afcac4716fc03 mock-3.0.5/000077500000000000000000000000001346437275100124645ustar00rootroot00000000000000mock-3.0.5/.carthorse.yml000066400000000000000000000003461346437275100152620ustar00rootroot00000000000000carthorse: version-from: setup.py tag-format: "{version}" when: - version-not-tagged actions: - run: "sudo pip install -e .[build]" - run: "twine upload -u carthorse-mock -p $PYPI_PASS dist/*" - create-tag mock-3.0.5/.circleci/000077500000000000000000000000001346437275100143175ustar00rootroot00000000000000mock-3.0.5/.circleci/config.yml000066400000000000000000000046311346437275100163130ustar00rootroot00000000000000version: 2.1 orbs: python: cjw296/python-ci@2 jobs: check-package: parameters: image: type: string python: type: string default: "python" docker: - image: << parameters.image >> steps: - python/check-package: package: "mock" test: - run: name: "Import package" command: << parameters.python >> -c "import mock" common: &common jobs: - python/pip-run-tests: name: python27 image: circleci/python:2.7 - python/pip-run-tests: name: python34 image: circleci/python:3.4 - python/pip-run-tests: name: python35 image: circleci/python:3.5 - python/pip-run-tests: name: python36 image: circleci/python:3.6 - python/pip-run-tests: name: python37 image: circleci/python:3.7 - python/pip-run-tests: name: pypy27 image: pypy:2.7 - python/pip-run-tests: name: pypy36 image: pypy:3.6 - python/coverage: name: coverage requires: - python27 - python34 - python35 - python36 - python37 - pypy27 - pypy36 - python/pip-docs: name: docs requires: - coverage - python/pip-setuptools-build-package: name: package requires: - docs filters: branches: only: master - check-package: name: check-package-python27 image: circleci/python:2.7 requires: - package - check-package: name: check-package-python37 image: circleci/python:3.7 requires: - package - check-package: name: check-package-pypy27 image: pypy:2.7 python: pypy requires: - package - check-package: name: check-package-pypy36 image: pypy:3.6 python: pypy3 requires: - package - python/release: name: release config: .carthorse.yml requires: - check-package-python27 - check-package-python37 - check-package-pypy27 - check-package-pypy36 workflows: push: <<: *common periodic: <<: *common triggers: - schedule: cron: "0 1 * * *" filters: branches: only: master mock-3.0.5/.coveragerc000066400000000000000000000002771346437275100146130ustar00rootroot00000000000000[run] source = mock omit = mock/tests/__main__.py [report] exclude_lines = pragma: no cover if __name__ == .__main__.: : pass [paths] source = mock/ /root/project/mock/ mock-3.0.5/.gitignore000066400000000000000000000002271346437275100144550ustar00rootroot00000000000000.*\.pyc html/ mock\.egg-info/ mock\.wpu \.tox/ build dist latex .*\$py\.class runtox *~ *.pyc .testrepository .*.swp README.html .coverage .coverage.* mock-3.0.5/.readthedocs.yml000066400000000000000000000001661346437275100155550ustar00rootroot00000000000000version: 2 python: version: 3.7 install: - method: pip path: . extra_requirements: - docs mock-3.0.5/CHANGELOG.rst000066400000000000000000000172571346437275100145210ustar00rootroot000000000000003.0.5 ----- - Issue #31855: :func:`unittest.mock.mock_open` results now respects the argument of read([size]). Patch contributed by Rémi Lapeyre. 3.0.4 ----- - Include the license, readme and changelog in the source distribution. 3.0.3 ----- - Fixed patching of dictionaries, when specifying the target with a unicode on Python 2. 3.0.2 ----- - Add missing ``funcsigs`` dependency on Python 2. 3.0.1 ----- - Fix packaging issue where ``six`` was missed as a dependency. 3.0.0 ----- - Issue #35226: Recursively check arguments when testing for equality of :class:`unittest.mock.call` objects and add note that tracking of parameters used to create ancestors of mocks in ``mock_calls`` is not possible. - Issue #31177: Fix bug that prevented using :meth:`reset_mock ` on mock instances with deleted attributes - Issue #26704: Added test demonstrating double-patching of an instance method. Patch by Anthony Sottile. - Issue #35500: Write expected and actual call parameters on separate lines in :meth:`unittest.mock.Mock.assert_called_with` assertion errors. Contributed by Susan Su. - Issue #35330: When a :class:`Mock` instance was used to wrap an object, if `side_effect` is used in one of the mocks of it methods, don't call the original implementation and return the result of using the side effect the same way that it is done with return_value. - Issue #30541: Add new function to seal a mock and prevent the automatically creation of child mocks. Patch by Mario Corchero. - Issue #35022: :class:`unittest.mock.MagicMock` now supports the ``__fspath__`` method (from :class:`os.PathLike`). - Issue #33516: :class:`unittest.mock.MagicMock` now supports the ``__round__`` magic method. - Issue #35512: :func:`unittest.mock.patch.dict` used as a decorator with string target resolves the target during function call instead of during decorator construction. Patch by Karthikeyan Singaravelan. - Issue #36366: Calling ``stop()`` on an unstarted or stopped :func:`unittest.mock.patch` object will now return `None` instead of raising :exc:`RuntimeError`, making the method idempotent. Patch byKarthikeyan Singaravelan. - Issue #35357: Internal attributes' names of unittest.mock._Call and unittest.mock.MagicProxy (name, parent & from_kall) are now prefixed with _mock_ in order to prevent clashes with widely used object attributes. Fixed minor typo in test function name. - Issue #20239: Allow repeated assignment deletion of :class:`unittest.mock.Mock` attributes. Patch by Pablo Galindo. - Issue #35082: Don't return deleted attributes when calling dir on a :class:`unittest.mock.Mock`. - Issue #0: Improved an error message when mock assert_has_calls fails. - Issue #23078: Add support for :func:`classmethod` and :func:`staticmethod` to :func:`unittest.mock.create_autospec`. Initial patch by Felipe Ochoa. - Issue #21478: Calls to a child function created with :func:`unittest.mock.create_autospec` should propagate to the parent. Patch by Karthikeyan Singaravelan. - Issue #36598: Fix ``isinstance`` check for Mock objects with spec when the code is executed under tracing. Patch by Karthikeyan Singaravelan. - Issue #32933: :func:`unittest.mock.mock_open` now supports iteration over the file contents. Patch by Tony Flury. - Issue #21269: Add ``args`` and ``kwargs`` properties to mock call objects. Contributed by Kumar Akshay. - Issue #17185: Set ``__signature__`` on mock for :mod:`inspect` to get signature. Patch by Karthikeyan Singaravelan. - Issue #35047: ``unittest.mock`` now includes mock calls in exception messages if ``assert_not_called``, ``assert_called_once``, or ``assert_called_once_with`` fails. Patch by Petter Strandmark. - Issue #28380: unittest.mock Mock autospec functions now properly support assert_called, assert_not_called, and assert_called_once. - Issue #28735: Fixed the comparison of mock.MagickMock with mock.ANY. - Issue #20804: The unittest.mock.sentinel attributes now preserve their identity when they are copied or pickled. - Issue #28961: Fix unittest.mock._Call helper: don't ignore the name parameter anymore. Patch written by Jiajun Huang. - Issue #26750: unittest.mock.create_autospec() now works properly for subclasses of property() and other data descriptors. - Issue #21271: New keyword only parameters in reset_mock call. - Issue #26807: mock_open 'files' no longer error on readline at end of file. Patch from Yolanda Robla. - Issue #25195: Fix a regression in mock.MagicMock. _Call is a subclass of tuple (changeset 3603bae63c13 only works for classes) so we need to implement __ne__ ourselves. Patch by Andrew Plummer. 2.0.0 and earlier ----------------- - Issue #26323: Add Mock.assert_called() and Mock.assert_called_once() methods to unittest.mock. Patch written by Amit Saha. - Issue #22138: Fix mock.patch behavior when patching descriptors. Restore original values after patching. Patch contributed by Sean McCully. - Issue #24857: Comparing call_args to a long sequence now correctly returns a boolean result instead of raising an exception. Patch by A Kaptur. - Issue #23004: mock_open() now reads binary data correctly when the type of read_data is bytes. Initial patch by Aaron Hill. - Issue #21750: mock_open.read_data can now be read from each instance, as it could in Python 3.3. - Issue #18622: unittest.mock.mock_open().reset_mock would recurse infinitely. Patch from Nicola Palumbo and Laurent De Buyst. - Issue #23661: unittest.mock side_effects can now be exceptions again. This was a regression vs Python 3.4. Patch from Ignacio Rossi - Issue #23310: Fix MagicMock's initializer to work with __methods__, just like configure_mock(). Patch by Kasia Jachim. - Issue #23568: Add rdivmod support to MagicMock() objects. Patch by Håkan Lövdahl. - Issue #23581: Add matmul support to MagicMock. Patch by Håkan Lövdahl. - Issue #23326: Removed __ne__ implementations. Since fixing default __ne__ implementation in issue #21408 they are redundant. *** NOT BACKPORTED *** - Issue #21270: We now override tuple methods in mock.call objects so that they can be used as normal call attributes. - Issue #21256: Printout of keyword args should be in deterministic order in a mock function call. This will help to write better doctests. - Issue #21262: New method assert_not_called for Mock. It raises AssertionError if the mock has been called. - Issue #21238: New keyword argument `unsafe` to Mock. It raises `AttributeError` incase of an attribute startswith assert or assret. - Issue #21239: patch.stopall() didn't work deterministically when the same name was patched more than once. - Issue #21222: Passing name keyword argument to mock.create_autospec now works. - Issue #17826: setting an iterable side_effect on a mock function created by create_autospec now works. Patch by Kushal Das. - Issue #17826: setting an iterable side_effect on a mock function created by create_autospec now works. Patch by Kushal Das. - Issue #20968: unittest.mock.MagicMock now supports division. Patch by Johannes Baiter. - Issue #20189: unittest.mock now no longer assumes that any object for which it could get an inspect.Signature is a callable written in Python. Fix courtesy of Michael Foord. - Issue #17467: add readline and readlines support to mock_open in unittest.mock. - Issue #17015: When it has a spec, a Mock object now inspects its signature when matching calls, so that arguments can be matched positionally or by name. - Issue #15323: improve failure message of Mock.assert_called_once_with - Issue #14857: fix regression in references to PEP 3135 implicit __class__ closure variable (Reopens issue #12370) - Issue #14295: Add unittest.mock mock-3.0.5/LICENSE.txt000066400000000000000000000024761346437275100143200ustar00rootroot00000000000000Copyright (c) 2003-2013, Michael Foord & the mock team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mock-3.0.5/MANIFEST.in000066400000000000000000000000421346437275100142160ustar00rootroot00000000000000include LICENSE.txt include *.rst mock-3.0.5/README.rst000066400000000000000000000027131346437275100141560ustar00rootroot00000000000000mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. mock is now part of the Python standard library, available as `unittest.mock `_ in Python 3.3 onwards. This package contains a rolling backport of the standard library mock code compatible with Python 2.7 and 3.4 and up. Please see the standard library documentation for more details. :Homepage: `Mock Homepage`_ :Download: `Mock on PyPI`_ :Documentation: `Python Docs`_ :License: `BSD License`_ :Support: `Mailing list (testing-in-python@lists.idyll.org) `_ :Code: `GitHub `_ :Issue tracker: `GitHub Issues `_ :Build status: |CircleCI|_ |Docs|_ .. |CircleCI| image:: https://circleci.com/gh/testing-cabal/mock/tree/master.svg?style=shield .. _CircleCI: https://circleci.com/gh/testing-cabal/mock/tree/master .. |Docs| image:: https://readthedocs.org/projects/mock/badge/?version=latest .. _Docs: http://mock.readthedocs.org/en/latest/ .. _Mock Homepage: http://mock.readthedocs.org/en/latest/ .. _BSD License: https://github.com/testing-cabal/mock/blob/master/LICENSE.txt .. _Python Docs: https://docs.python.org/dev/library/unittest.mock.html .. _mock on PyPI: https://pypi.org/project/mock/ mock-3.0.5/backport.py000066400000000000000000000103371346437275100146470ustar00rootroot00000000000000import re from argparse import ArgumentParser from os.path import dirname, abspath, join from subprocess import check_output, call def git(command, repo): return check_output('git '+command, cwd=repo, shell=True).decode() def repo_state_bad(mock_repo): status = git('status', mock_repo) if 'You are in the middle of an am session' in status: print(f'Mock repo at {mock_repo} needs cleanup:\n') call('git status', shell=True) return True def cleanup_old_patches(mock_repo): print('cleaning up old patches:') call('rm -vf /tmp/*.mock.patch', shell=True) call('find . -name "*.rej" -print -delete', shell=True, cwd=mock_repo) def find_initial_cpython_rev(): with open('lastsync.txt') as source: return source.read().strip() def cpython_revs_affecting_mock(cpython_repo, start): revs = git(f'log --no-merges --format=%H {start}.. ' f'-- Lib/unittest/mock.py Lib/unittest/test/testmock/', repo=cpython_repo).split() revs.reverse() print(f'{len(revs)} patches that may need backporting') return revs def has_been_backported(mock_repo, cpython_rev): backport_rev = git(f'log --format=%H --grep "Backports: {cpython_rev}"', repo=mock_repo).strip() if backport_rev: print(f'{cpython_rev} backported in {backport_rev}') return True print(f'{cpython_rev} has not been backported') def extract_patch_for(cpython_repo, rev): return git(f'format-patch -1 --no-stat --keep-subject --signoff --stdout {rev}', repo=cpython_repo) def munge(rev, patch): sign_off = 'Signed-off-by:' patch = patch.replace(sign_off, f'Backports: {rev}\n{sign_off}', 1) for pattern, sub in ( ('(a|b)/Lib/unittest/mock.py', r'\1/mock/mock.py'), (r'(a|b)/Lib/unittest/test/testmock/(\S+)', r'\1/mock/tests/\2'), ('(a|b)/Misc/NEWS', r'\1/NEWS'), ('(a|b)/NEWS.d/next/[^/]+/(.+\.rst)', r'\1/NEWS.d/\2'), ): patch = re.sub(pattern, sub, patch) return patch def apply_patch(mock_repo, rev, patch): patch_path = f'/tmp/{rev}.mock.patch' with open(patch_path, 'w') as target: target.write(patch) print(f'wrote {patch_path}') call(f'git am -k ' f'--include "mock/*" --include NEWS --include "NEWS.d/*" ' f'--reject {patch_path} ', cwd=mock_repo, shell=True) def update_last_sync(mock_repo, rev): with open(join(mock_repo, 'lastsync.txt'), 'w') as target: target.write(rev+'\n') print(f'update lastsync.txt to {rev}') def rev_from_mock_patch(text): match = re.search('Backports: ([a-z0-9]+)', text) return match.group(1) def skip_current(mock_repo, reason): text = git('am --show-current-patch', repo=mock_repo) rev = rev_from_mock_patch(text) git('am --abort', repo=mock_repo) print(f'skipping {rev}') update_last_sync(mock_repo, rev) call(f'git commit -m "Backports: {rev}, skipped: {reason}" lastsync.txt', shell=True, cwd=mock_repo) cleanup_old_patches(mock_repo) def commit_last_sync(revs, mock_repo): print('Yay! All caught up!') if len(revs): git('commit -m "latest sync point" lastsync.txt', repo=mock_repo) def main(): args = parse_args() if args.skip_current: return skip_current(args.mock, args.skip_reason) if repo_state_bad(args.mock): return cleanup_old_patches(args.mock) initial_cpython_rev = find_initial_cpython_rev() revs = cpython_revs_affecting_mock(args.cpython, initial_cpython_rev) for rev in revs: if has_been_backported(args.mock, rev): update_last_sync(args.mock, rev) continue patch = extract_patch_for(args.cpython, rev) patch = munge(rev, patch) apply_patch(args.mock, rev, patch) break else: commit_last_sync(revs, args.mock) def parse_args(): parser = ArgumentParser() parser.add_argument('--cpython', default='../cpython') parser.add_argument('--mock', default=abspath(dirname(__file__))) parser.add_argument('--skip-current', action='store_true') parser.add_argument('--skip-reason', default='it has no changes needed here.') return parser.parse_args() if __name__ == '__main__': main() mock-3.0.5/docs/000077500000000000000000000000001346437275100134145ustar00rootroot00000000000000mock-3.0.5/docs/changelog.txt000066400000000000000000000000631346437275100161030ustar00rootroot00000000000000Changelog ========= .. include:: ../CHANGELOG.rst mock-3.0.5/docs/conf.py000066400000000000000000000141261346437275100147170ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Mock documentation build configuration file, created by # sphinx-quickstart on Mon Nov 17 18:12:00 2008. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # All configuration values have a default value; values that are commented out # serve to show the default value. import sys, os sys.path.insert(0, os.path.abspath('..')) import mock # If your extensions are in another directory, add it here. If the directory # is relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. #sys.path.append(os.path.abspath('some/directory')) # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.doctest'] doctest_global_setup = """ import os import sys import mock from mock import * # yeah, I know :-/ import __main__ if os.getcwd() not in sys.path: sys.path.append(os.getcwd()) # keep a reference to __main__ sys.modules['__main'] = __main__ class ProxyModule(object): def __init__(self): self.__dict__ = globals() sys.modules['__main__'] = ProxyModule() """ doctest_global_cleanup = """ sys.modules['__main__'] = sys.modules['__main'] """ html_theme = 'nature' html_theme_options = {} # Add any paths that contain templates here, relative to this directory. #templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.txt' # The master toctree document. master_doc = 'index' # General substitutions. project = u'Mock' copyright = u'2007-2015, Michael Foord & the mock team' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. Supplied by pbr. # version = release = mock.mock.__version__ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: (Set from pbr) today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directories, that shouldn't be searched # for source files. exclude_trees = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = False # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'friendly' # Options for HTML output # ----------------------- # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. #html_style = 'adctheme.css' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. html_use_modindex = False # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'Mockdoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). latex_font_size = '12pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('index', 'Mock.tex', u'Mock Documentation', u'Michael Foord', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. latex_use_modindex = False mock-3.0.5/docs/index.txt000066400000000000000000000116531346437275100152720ustar00rootroot00000000000000=================================== Mock - Mocking and Testing Library =================================== .. include:: ../README.rst .. module:: mock :synopsis: Mock object and testing library. .. index:: introduction .. toctree:: :hidden: changelog Python Version Compatibility ++++++++++++++++++++++++++++ * Version 1.0.1 is the last version compatible with Python < 2.6. * Version 1.3.0 is the last version compatible with Python 3.2. * Version 2.0.0 is the last version compatible with Python 2.6. * Version 2.0.0 is the last version offering official Jython support. .. index:: installing .. _installing: Installing ++++++++++ .. index:: repository .. index:: git You can checkout the latest development version from GitHub repository with the following command: ``git clone https://github.com/testing-cabal/mock.git`` .. index:: pip You can install mock with pip: | ``pip install -U mock`` .. index:: bug reports Bug Reports +++++++++++ Issues with the backport process, such as compatibility with a particular Python, should be reported to the `bug tracker `_. Feature requests and issues with Mock functionality should be reported to the `Python bug tracker `_. .. index:: python changes Changelog +++++++++ See the :doc:`change log `. .. index:: maintainer notes Maintainer Notes ++++++++++++++++ Development ----------- Checkout from git (see :ref:`installing`) and submit pull requests. Committers can just push as desired: since all semantic development takes place in cPython, the backport process is as lightweight as we can make it. mock is CI tested using Travis-CI on Python versions 2.7, 3.4, 3.5, 3.6, pypy, pypy3. If you end up fixing anything backport-specific, please add an entry to the top of ``CHANGELOG.rst`` so it shows up in the next release notes. Releasing --------- NB: please use semver. Bump the major component on API breaks, minor on all non-bugfix changes, patch on bugfix only changes. 1. Run ``release.py [major|minor|bugfix]`` which will roll out new NEWS items, bump the version number and create a commit for the release. 2. Review that commit, feel free to amend it if you want to note anything manually in ``CHANGELOG.rst``. 3. Push to the ``master`` branch on https://github.com/testing-cabal/mock.git and the Circle CI automation will take care of pushing releases to PyPI and creating a tag. Backporting rules ----------------- - ``isinstance`` checks in cPython to ``type`` need to check ``ClassTypes``. Code calling ``obj.isidentifier`` needs to change to ``_isidentifier(obj)``. - f-strings need to be rewritten using some other string substitution. - ``assertRaisesRegex`` needs to be ``assertRaisesRegexp`` for Python 2. - If test code won't compile on a particular version of Python, move it to a matching ``_py{version}.py`` file. If ``{version}`` isn't 3, adjust ``conftest.py``. - If code such as this causes coverage checking to drop below 100%: .. code-block:: python def will_never_be_called(): pass It should be adjusted to the following pattern, preferably upstream, so that the ``.coveragerc`` in this repo knows to ignore it: .. code-block:: python def will_never_be_called(): pass Backporting process ------------------- 1. Clone cpython and mock into the same directory, eg: .. code-block:: bash mkdir vcs cd vcs git clone https://github.com/python/cpython.git git clone https://github.com/testing-cabal/mock.git Make sure they both on master and up to date! 2. Create a branch in your ``mock`` clone and switch to it. 3. Make sure you build a suitable virtualenv for Mock development and activate it. For backporting, this should use Python 3.7+. 4. Run ``backport.py``: .. code-block:: bash cd vcs/mock python backport.py This will find the next cpython patch that needs to be applied, munge it and attempt to apply it with ``git am``. If it succeeds, run the tests and/or push your branch up to a fork and do a pull request into the master branch of the main repo to kick off the continuous integration tests. If it fails, you'll have to manually work with what ``git status`` shows to get the patch committed. If it turns out that there's nothing that should be applied from the failed commit, run ``python backport.py --skip-current``, maybe with ``--skip-reason``. If you have to make changes, please do a ``git commit --amend`` and add notes about what needed doing below the ``Signed-off-by`` block. If you have to make changes because tests fail with an applied patch, please make those changes in a followup commit and take note of the "Backporting rules" above. 5. Rinse and repeat until ``backport.py`` reports no more patches need applying. 6. If ``backport.py`` has updated ``lastsync.txt``, now would be a good time to commit that change. mock-3.0.5/lastsync.txt000066400000000000000000000000511346437275100150610ustar00rootroot0000000000000011a8832c98b3db78727312154dd1d3ba76d639ec mock-3.0.5/mock/000077500000000000000000000000001346437275100134155ustar00rootroot00000000000000mock-3.0.5/mock/__init__.py000066400000000000000000000001611346437275100155240ustar00rootroot00000000000000from __future__ import absolute_import import mock.mock as _mock from mock.mock import * __all__ = _mock.__all__ mock-3.0.5/mock/mock.py000066400000000000000000002504751346437275100147350ustar00rootroot00000000000000# mock.py # Test tools for mocking and patching. # E-mail: fuzzyman AT voidspace DOT org DOT uk # # http://www.voidspace.org.uk/python/mock/ # # Copyright (c) 2007-2013, Michael Foord & the mock team # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from __future__ import absolute_import __all__ = ( '__version__', 'version_info', 'Mock', 'MagicMock', 'patch', 'sentinel', 'DEFAULT', 'ANY', 'call', 'create_autospec', 'FILTER_DIR', 'CallableMixin', 'NonCallableMock', 'NonCallableMagicMock', 'mock_open', 'PropertyMock', 'seal', ) from functools import partial import io import inspect import pprint import sys try: import builtins except ImportError: import __builtin__ as builtins from types import ModuleType, MethodType from unittest.util import safe_repr import six from six import wraps __version__ = '3.0.5' version_info = tuple(int(p) for p in __version__.split('.')) import mock try: inspectsignature = inspect.signature except AttributeError: import funcsigs inspectsignature = funcsigs.signature # TODO: use six. try: unicode except NameError: # Python 3 basestring = unicode = str try: long except NameError: # Python 3 long = int if six.PY2: # Python 2's next() can't handle a non-iterator with a __next__ method. _next = next def next(obj, _next=_next): if getattr(obj, '__next__', None): return obj.__next__() return _next(obj) del _next _builtins = {name for name in dir(builtins) if not name.startswith('_')} try: _isidentifier = str.isidentifier except AttributeError: # Python 2.X import keyword import re regex = re.compile(r'^[a-z_][a-z0-9_]*$', re.I) def _isidentifier(string): if string in keyword.kwlist: return False return regex.match(string) # NOTE: This FILTER_DIR is not used. The binding in mock.FILTER_DIR is. FILTER_DIR = True # Workaround for Python issue #12370 # Without this, the __class__ properties wouldn't be set correctly _safe_super = super def _is_instance_mock(obj): # can't use isinstance on Mock objects because they override __class__ # The base class for all mocks is NonCallableMock return issubclass(type(obj), NonCallableMock) def _is_exception(obj): return ( isinstance(obj, BaseException) or isinstance(obj, ClassTypes) and issubclass(obj, BaseException) ) class _slotted(object): __slots__ = ['a'] # Do not use this tuple. It was never documented as a public API. # It will be removed. It has no obvious signs of users on github. DescriptorTypes = ( type(_slotted.a), property, ) def _get_signature_object(func, as_instance, eat_self): """ Given an arbitrary, possibly callable object, try to create a suitable signature object. Return a (reduced func, signature) tuple, or None. """ if isinstance(func, ClassTypes) and not as_instance: # If it's a type and should be modelled as a type, use __init__. try: func = func.__init__ except AttributeError: return None # Skip the `self` argument in __init__ eat_self = True elif not isinstance(func, FunctionTypes): # If we really want to model an instance of the passed type, # __call__ should be looked up, not __init__. try: func = func.__call__ except AttributeError: return None if eat_self: sig_func = partial(func, None) else: sig_func = func try: return func, inspectsignature(sig_func) except ValueError: # Certain callable types are not supported by inspect.signature() return None def _check_signature(func, mock, skipfirst, instance=False): sig = _get_signature_object(func, instance, skipfirst) if sig is None: return func, sig = sig def checksig(_mock_self, *args, **kwargs): sig.bind(*args, **kwargs) _copy_func_details(func, checksig) type(mock)._mock_check_sig = checksig type(mock).__signature__ = sig def _copy_func_details(func, funcopy): # we explicitly don't copy func.__dict__ into this copy as it would # expose original attributes that should be mocked for attribute in ( '__name__', '__doc__', '__text_signature__', '__module__', '__defaults__', '__kwdefaults__', ): try: setattr(funcopy, attribute, getattr(func, attribute)) except AttributeError: pass if six.PY2: try: funcopy.func_defaults = func.func_defaults except AttributeError: pass def _callable(obj): if isinstance(obj, ClassTypes): return True if isinstance(obj, (staticmethod, classmethod, MethodType)): return _callable(obj.__func__) if getattr(obj, '__call__', None) is not None: return True return False def _is_list(obj): # checks for list or tuples # XXXX badly named! return type(obj) in (list, tuple) def _instance_callable(obj): """Given an object, return True if the object is callable. For classes, return True if instances would be callable.""" if not isinstance(obj, ClassTypes): # already an instance return getattr(obj, '__call__', None) is not None if six.PY3: # *could* be broken by a class overriding __mro__ or __dict__ via # a metaclass for base in (obj,) + obj.__mro__: if base.__dict__.get('__call__') is not None: return True else: klass = obj # uses __bases__ instead of __mro__ so that we work with old style classes if klass.__dict__.get('__call__') is not None: return True for base in klass.__bases__: if _instance_callable(base): return True return False def _set_signature(mock, original, instance=False): # creates a function with signature (*args, **kwargs) that delegates to a # mock. It still does signature checking by calling a lambda with the same # signature as the original. skipfirst = isinstance(original, ClassTypes) result = _get_signature_object(original, instance, skipfirst) if result is None: return mock func, sig = result def checksig(*args, **kwargs): sig.bind(*args, **kwargs) _copy_func_details(func, checksig) name = original.__name__ if not _isidentifier(name): name = 'funcopy' context = {'_checksig_': checksig, 'mock': mock} src = """def %s(*args, **kwargs): _checksig_(*args, **kwargs) return mock(*args, **kwargs)""" % name six.exec_(src, context) funcopy = context[name] _setup_func(funcopy, mock, sig) return funcopy def _setup_func(funcopy, mock, sig): funcopy.mock = mock def assert_called(*args, **kwargs): return mock.assert_called(*args, **kwargs) def assert_not_called(*args, **kwargs): return mock.assert_not_called(*args, **kwargs) def assert_called_once(*args, **kwargs): return mock.assert_called_once(*args, **kwargs) def assert_called_with(*args, **kwargs): return mock.assert_called_with(*args, **kwargs) def assert_called_once_with(*args, **kwargs): return mock.assert_called_once_with(*args, **kwargs) def assert_has_calls(*args, **kwargs): return mock.assert_has_calls(*args, **kwargs) def assert_any_call(*args, **kwargs): return mock.assert_any_call(*args, **kwargs) def reset_mock(): funcopy.method_calls = _CallList() funcopy.mock_calls = _CallList() mock.reset_mock() ret = funcopy.return_value if _is_instance_mock(ret) and not ret is mock: ret.reset_mock() funcopy.called = False funcopy.call_count = 0 funcopy.call_args = None funcopy.call_args_list = _CallList() funcopy.method_calls = _CallList() funcopy.mock_calls = _CallList() funcopy.return_value = mock.return_value funcopy.side_effect = mock.side_effect funcopy._mock_children = mock._mock_children funcopy.assert_called_with = assert_called_with funcopy.assert_called_once_with = assert_called_once_with funcopy.assert_has_calls = assert_has_calls funcopy.assert_any_call = assert_any_call funcopy.reset_mock = reset_mock funcopy.assert_called = assert_called funcopy.assert_not_called = assert_not_called funcopy.assert_called_once = assert_called_once funcopy.__signature__ = sig mock._mock_delegate = funcopy def _is_magic(name): return '__%s__' % name[2:-2] == name class _SentinelObject(object): "A unique, named, sentinel object." def __init__(self, name): self.name = name def __repr__(self): return 'sentinel.%s' % self.name def __reduce__(self): return _unpickle_sentinel, (self.name, ) def _unpickle_sentinel(name): return getattr(sentinel, name) class _Sentinel(object): """Access attributes to return a named object, usable as a sentinel.""" def __init__(self): self._sentinels = {} def __getattr__(self, name): if name == '__bases__': # Without this help(unittest.mock) raises an exception raise AttributeError return self._sentinels.setdefault(name, _SentinelObject(name)) sentinel = _Sentinel() DEFAULT = sentinel.DEFAULT _missing = sentinel.MISSING _deleted = sentinel.DELETED class OldStyleClass: pass ClassType = type(OldStyleClass) ClassTypes = (type,) if six.PY2: ClassTypes = (type, ClassType) _allowed_names = { 'return_value', '_mock_return_value', 'side_effect', '_mock_side_effect', '_mock_parent', '_mock_new_parent', '_mock_name', '_mock_new_name' } def _delegating_property(name): _allowed_names.add(name) _the_name = '_mock_' + name def _get(self, name=name, _the_name=_the_name): sig = self._mock_delegate if sig is None: return getattr(self, _the_name) return getattr(sig, name) def _set(self, value, name=name, _the_name=_the_name): sig = self._mock_delegate if sig is None: self.__dict__[_the_name] = value else: setattr(sig, name, value) return property(_get, _set) class _CallList(list): def __contains__(self, value): if not isinstance(value, list): return list.__contains__(self, value) len_value = len(value) len_self = len(self) if len_value > len_self: return False for i in range(0, len_self - len_value + 1): sub_list = self[i:i+len_value] if sub_list == value: return True return False def __repr__(self): return pprint.pformat(list(self)) def _check_and_set_parent(parent, value, name, new_name): # function passed to create_autospec will have mock # attribute attached to which parent must be set if isinstance(value, FunctionTypes): try: value = value.mock except AttributeError: pass if not _is_instance_mock(value): return False if ((value._mock_name or value._mock_new_name) or (value._mock_parent is not None) or (value._mock_new_parent is not None)): return False _parent = parent while _parent is not None: # setting a mock (value) as a child or return value of itself # should not modify the mock if _parent is value: return False _parent = _parent._mock_new_parent if new_name: value._mock_new_parent = parent value._mock_new_name = new_name if name: value._mock_parent = parent value._mock_name = name return True # Internal class to identify if we wrapped an iterator object or not. class _MockIter(object): def __init__(self, obj): self.obj = iter(obj) def __next__(self): return next(self.obj) class Base(object): _mock_return_value = DEFAULT _mock_side_effect = None def __init__(self, *args, **kwargs): pass class NonCallableMock(Base): """A non-callable version of `Mock`""" def __new__(cls, *args, **kw): # every instance has its own class # so we can create magic methods on the # class without stomping on other mocks new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__}) instance = object.__new__(new) return instance def __init__( self, spec=None, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs ): if _new_parent is None: _new_parent = parent __dict__ = self.__dict__ __dict__['_mock_parent'] = parent __dict__['_mock_name'] = name __dict__['_mock_new_name'] = _new_name __dict__['_mock_new_parent'] = _new_parent __dict__['_mock_sealed'] = False if spec_set is not None: spec = spec_set spec_set = True if _eat_self is None: _eat_self = parent is not None self._mock_add_spec(spec, spec_set, _spec_as_instance, _eat_self) __dict__['_mock_children'] = {} __dict__['_mock_wraps'] = wraps __dict__['_mock_delegate'] = None __dict__['_mock_called'] = False __dict__['_mock_call_args'] = None __dict__['_mock_call_count'] = 0 __dict__['_mock_call_args_list'] = _CallList() __dict__['_mock_mock_calls'] = _CallList() __dict__['method_calls'] = _CallList() __dict__['_mock_unsafe'] = unsafe if kwargs: self.configure_mock(**kwargs) _safe_super(NonCallableMock, self).__init__( spec, wraps, name, spec_set, parent, _spec_state ) def attach_mock(self, mock, attribute): """ Attach a mock as an attribute of this one, replacing its name and parent. Calls to the attached mock will be recorded in the `method_calls` and `mock_calls` attributes of this one.""" mock._mock_parent = None mock._mock_new_parent = None mock._mock_name = '' mock._mock_new_name = None setattr(self, attribute, mock) def mock_add_spec(self, spec, spec_set=False): """Add a spec to a mock. `spec` can either be an object or a list of strings. Only attributes on the `spec` can be fetched as attributes from the mock. If `spec_set` is True then only attributes on the spec can be set.""" self._mock_add_spec(spec, spec_set) def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, _eat_self=False): _spec_class = None _spec_signature = None if spec is not None and not _is_list(spec): if isinstance(spec, ClassTypes): _spec_class = spec else: _spec_class = type(spec) res = _get_signature_object(spec, _spec_as_instance, _eat_self) _spec_signature = res and res[1] spec = dir(spec) __dict__ = self.__dict__ __dict__['_spec_class'] = _spec_class __dict__['_spec_set'] = spec_set __dict__['_spec_signature'] = _spec_signature __dict__['_mock_methods'] = spec def __get_return_value(self): ret = self._mock_return_value if self._mock_delegate is not None: ret = self._mock_delegate.return_value if ret is DEFAULT: ret = self._get_child_mock( _new_parent=self, _new_name='()' ) self.return_value = ret return ret def __set_return_value(self, value): if self._mock_delegate is not None: self._mock_delegate.return_value = value else: self._mock_return_value = value _check_and_set_parent(self, value, None, '()') __return_value_doc = "The value to be returned when the mock is called." return_value = property(__get_return_value, __set_return_value, __return_value_doc) @property def __class__(self): if self._spec_class is None: return type(self) return self._spec_class called = _delegating_property('called') call_count = _delegating_property('call_count') call_args = _delegating_property('call_args') call_args_list = _delegating_property('call_args_list') mock_calls = _delegating_property('mock_calls') def __get_side_effect(self): delegated = self._mock_delegate if delegated is None: return self._mock_side_effect sf = delegated.side_effect if (sf is not None and not callable(sf) and not isinstance(sf, _MockIter) and not _is_exception(sf)): sf = _MockIter(sf) delegated.side_effect = sf return sf def __set_side_effect(self, value): value = _try_iter(value) delegated = self._mock_delegate if delegated is None: self._mock_side_effect = value else: delegated.side_effect = value side_effect = property(__get_side_effect, __set_side_effect) def reset_mock(self, visited=None, return_value=False, side_effect=False): "Restore the mock object to its initial state." if visited is None: visited = [] if id(self) in visited: return visited.append(id(self)) self.called = False self.call_args = None self.call_count = 0 self.mock_calls = _CallList() self.call_args_list = _CallList() self.method_calls = _CallList() if return_value: self._mock_return_value = DEFAULT if side_effect: self._mock_side_effect = None for child in self._mock_children.values(): if isinstance(child, _SpecState) or child is _deleted: continue child.reset_mock(visited) ret = self._mock_return_value if _is_instance_mock(ret) and ret is not self: ret.reset_mock(visited) def configure_mock(self, **kwargs): """Set attributes on the mock through keyword arguments. Attributes plus return values and side effects can be set on child mocks using standard dot notation and unpacking a dictionary in the method call: >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError} >>> mock.configure_mock(**attrs)""" for arg, val in sorted(kwargs.items(), # we sort on the number of dots so that # attributes are set before we set attributes on # attributes key=lambda entry: entry[0].count('.')): args = arg.split('.') final = args.pop() obj = self for entry in args: obj = getattr(obj, entry) setattr(obj, final, val) def __getattr__(self, name): if name in ('_mock_methods', '_mock_unsafe'): raise AttributeError(name) elif self._mock_methods is not None: if name not in self._mock_methods or name in _all_magics: raise AttributeError("Mock object has no attribute %r" % name) elif _is_magic(name): raise AttributeError(name) if not self._mock_unsafe: if name.startswith(('assert', 'assret')): raise AttributeError(name) result = self._mock_children.get(name) if result is _deleted: raise AttributeError(name) elif result is None: wraps = None if self._mock_wraps is not None: # XXXX should we get the attribute without triggering code # execution? wraps = getattr(self._mock_wraps, name) result = self._get_child_mock( parent=self, name=name, wraps=wraps, _new_name=name, _new_parent=self ) self._mock_children[name] = result elif isinstance(result, _SpecState): result = create_autospec( result.spec, result.spec_set, result.instance, result.parent, result.name ) self._mock_children[name] = result return result def _extract_mock_name(self): _name_list = [self._mock_new_name] _parent = self._mock_new_parent last = self dot = '.' if _name_list == ['()']: dot = '' while _parent is not None: last = _parent _name_list.append(_parent._mock_new_name + dot) dot = '.' if _parent._mock_new_name == '()': dot = '' _parent = _parent._mock_new_parent _name_list = list(reversed(_name_list)) _first = last._mock_name or 'mock' if len(_name_list) > 1: if _name_list[1] not in ('()', '().'): _first += '.' _name_list[0] = _first return ''.join(_name_list) def __repr__(self): name = self._extract_mock_name() name_string = '' if name not in ('mock', 'mock.'): name_string = ' name=%r' % name spec_string = '' if self._spec_class is not None: spec_string = ' spec=%r' if self._spec_set: spec_string = ' spec_set=%r' spec_string = spec_string % self._spec_class.__name__ return "<{}{}{} id='{}'>".format( type(self).__name__, name_string, spec_string, id(self) ) def __dir__(self): """Filter the output of `dir(mock)` to only useful members.""" if not mock.FILTER_DIR and getattr(object, '__dir__', None): # object.__dir__ is not in 2.7 return object.__dir__(self) extras = self._mock_methods or [] from_type = dir(type(self)) from_dict = list(self.__dict__) from_child_mocks = [ m_name for m_name, m_value in self._mock_children.items() if m_value is not _deleted] if mock.FILTER_DIR: # object.__dir__ is not in 2.7 from_type = [e for e in from_type if not e.startswith('_')] from_dict = [e for e in from_dict if not e.startswith('_') or _is_magic(e)] return sorted(set(extras + from_type + from_dict + from_child_mocks)) def __setattr__(self, name, value): if name in _allowed_names: # property setters go through here return object.__setattr__(self, name, value) elif (self._spec_set and self._mock_methods is not None and name not in self._mock_methods and name not in self.__dict__): raise AttributeError("Mock object has no attribute '%s'" % name) elif name in _unsupported_magics: msg = 'Attempting to set unsupported magic method %r.' % name raise AttributeError(msg) elif name in _all_magics: if self._mock_methods is not None and name not in self._mock_methods: raise AttributeError("Mock object has no attribute '%s'" % name) if not _is_instance_mock(value): setattr(type(self), name, _get_method(name, value)) original = value value = lambda *args, **kw: original(self, *args, **kw) else: # only set _new_name and not name so that mock_calls is tracked # but not method calls _check_and_set_parent(self, value, None, name) setattr(type(self), name, value) self._mock_children[name] = value elif name == '__class__': self._spec_class = value return else: if _check_and_set_parent(self, value, name, name): self._mock_children[name] = value if self._mock_sealed and not hasattr(self, name): mock_name = self._extract_mock_name()+'.'+name raise AttributeError('Cannot set '+mock_name) return object.__setattr__(self, name, value) def __delattr__(self, name): if name in _all_magics and name in type(self).__dict__: delattr(type(self), name) if name not in self.__dict__: # for magic methods that are still MagicProxy objects and # not set on the instance itself return obj = self._mock_children.get(name, _missing) if name in self.__dict__: _safe_super(NonCallableMock, self).__delattr__(name) elif obj is _deleted: raise AttributeError(name) if obj is not _missing: del self._mock_children[name] self._mock_children[name] = _deleted def _format_mock_call_signature(self, args, kwargs): name = self._mock_name or 'mock' return _format_call_signature(name, args, kwargs) def _format_mock_failure_message(self, args, kwargs): message = 'expected call not found.\nExpected: %s\nActual: %s' expected_string = self._format_mock_call_signature(args, kwargs) call_args = self.call_args actual_string = self._format_mock_call_signature(*call_args) return message % (expected_string, actual_string) def _call_matcher(self, _call): """ Given a call (or simply an (args, kwargs) tuple), return a comparison key suitable for matching with other calls. This is a best effort method which relies on the spec's signature, if available, or falls back on the arguments themselves. """ sig = self._spec_signature if sig is not None: if len(_call) == 2: name = '' args, kwargs = _call else: name, args, kwargs = _call try: return name, sig.bind(*args, **kwargs) except TypeError as e: e.__traceback__ = None return e else: return _call def assert_not_called(_mock_self): """assert that the mock was never called. """ self = _mock_self if self.call_count != 0: msg = ("Expected '%s' to not have been called. Called %s times.%s" % (self._mock_name or 'mock', self.call_count, self._calls_repr())) raise AssertionError(msg) def assert_called(_mock_self): """assert that the mock was called at least once """ self = _mock_self if self.call_count == 0: msg = ("Expected '%s' to have been called." % self._mock_name or 'mock') raise AssertionError(msg) def assert_called_once(_mock_self): """assert that the mock was called only once. """ self = _mock_self if not self.call_count == 1: msg = ("Expected '%s' to have been called once. Called %s times.%s" % (self._mock_name or 'mock', self.call_count, self._calls_repr())) raise AssertionError(msg) def assert_called_with(_mock_self, *args, **kwargs): """assert that the mock was called with the specified arguments. Raises an AssertionError if the args and keyword args passed in are different to the last call to the mock.""" self = _mock_self if self.call_args is None: expected = self._format_mock_call_signature(args, kwargs) actual = 'not called.' error_message = ('expected call not found.\nExpected: %s\nActual: %s' % (expected, actual)) raise AssertionError(error_message) def _error_message(cause): msg = self._format_mock_failure_message(args, kwargs) if six.PY2 and cause is not None: # Tack on some diagnostics for Python without __cause__ msg = '{}\n{}'.format(msg, str(cause)) return msg expected = self._call_matcher((args, kwargs)) actual = self._call_matcher(self.call_args) if expected != actual: cause = expected if isinstance(expected, Exception) else None six.raise_from(AssertionError(_error_message(cause)), cause) def assert_called_once_with(_mock_self, *args, **kwargs): """assert that the mock was called exactly once and that that call was with the specified arguments.""" self = _mock_self if not self.call_count == 1: msg = ("Expected '%s' to be called once. Called %s times.%s" % (self._mock_name or 'mock', self.call_count, self._calls_repr())) raise AssertionError(msg) return self.assert_called_with(*args, **kwargs) def assert_has_calls(self, calls, any_order=False): """assert the mock has been called with the specified calls. The `mock_calls` list is checked for the calls. If `any_order` is False (the default) then the calls must be sequential. There can be extra calls before or after the specified calls. If `any_order` is True then the calls can be in any order, but they must all appear in `mock_calls`.""" expected = [self._call_matcher(c) for c in calls] cause = expected if isinstance(expected, Exception) else None all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls) if not any_order: if expected not in all_calls: six.raise_from(AssertionError( 'Calls not found.\nExpected: %r%s' % (_CallList(calls), self._calls_repr(prefix="Actual")) ), cause) return all_calls = list(all_calls) not_found = [] for kall in expected: try: all_calls.remove(kall) except ValueError: not_found.append(kall) if not_found: six.raise_from(AssertionError( '%r does not contain all of %r in its call list, ' 'found %r instead' % (self._mock_name or 'mock', tuple(not_found), all_calls) ), cause) def assert_any_call(self, *args, **kwargs): """assert the mock has been called with the specified arguments. The assert passes if the mock has *ever* been called, unlike `assert_called_with` and `assert_called_once_with` that only pass if the call is the most recent one.""" expected = self._call_matcher((args, kwargs)) actual = [self._call_matcher(c) for c in self.call_args_list] if expected not in actual: cause = expected if isinstance(expected, Exception) else None expected_string = self._format_mock_call_signature(args, kwargs) six.raise_from(AssertionError( '%s call not found' % expected_string ), cause) def _get_child_mock(self, **kw): """Create the child mocks for attributes and return value. By default child mocks will be the same type as the parent. Subclasses of Mock may want to override this to customize the way child mocks are made. For non-callable mocks the callable variant will be used (rather than any custom subclass).""" _type = type(self) if not issubclass(_type, CallableMixin): if issubclass(_type, NonCallableMagicMock): klass = MagicMock elif issubclass(_type, NonCallableMock) : klass = Mock else: klass = _type.__mro__[1] if self._mock_sealed: attribute = "." + kw["name"] if "name" in kw else "()" mock_name = self._extract_mock_name() + attribute raise AttributeError(mock_name) return klass(**kw) def _calls_repr(self, prefix="Calls"): """Renders self.mock_calls as a string. Example: "\nCalls: [call(1), call(2)]." If self.mock_calls is empty, an empty string is returned. The output will be truncated if very long. """ if not self.mock_calls: return "" return "\n"+prefix+": "+safe_repr(self.mock_calls)+"." def _try_iter(obj): if obj is None: return obj if _is_exception(obj): return obj if _callable(obj): return obj try: return iter(obj) except TypeError: # XXXX backwards compatibility # but this will blow up on first call - so maybe we should fail early? return obj class CallableMixin(Base): def __init__(self, spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, **kwargs): self.__dict__['_mock_return_value'] = return_value _safe_super(CallableMixin, self).__init__( spec, wraps, name, spec_set, parent, _spec_state, _new_name, _new_parent, **kwargs ) self.side_effect = side_effect def _mock_check_sig(self, *args, **kwargs): # stub method that can be replaced with one with a specific signature pass def __call__(_mock_self, *args, **kwargs): # can't use self in-case a function / method we are mocking uses self # in the signature _mock_self._mock_check_sig(*args, **kwargs) return _mock_self._mock_call(*args, **kwargs) def _mock_call(_mock_self, *args, **kwargs): self = _mock_self self.called = True self.call_count += 1 # handle call_args _call = _Call((args, kwargs), two=True) self.call_args = _call self.call_args_list.append(_call) # initial stuff for method_calls: do_method_calls = self._mock_parent is not None method_call_name = self._mock_name # initial stuff for mock_calls: mock_call_name = self._mock_new_name is_a_call = mock_call_name == '()' self.mock_calls.append(_Call(('', args, kwargs))) # follow up the chain of mocks: _new_parent = self._mock_new_parent while _new_parent is not None: # handle method_calls: if do_method_calls: _new_parent.method_calls.append(_Call((method_call_name, args, kwargs))) do_method_calls = _new_parent._mock_parent is not None if do_method_calls: method_call_name = _new_parent._mock_name + '.' + method_call_name # handle mock_calls: this_mock_call = _Call((mock_call_name, args, kwargs)) _new_parent.mock_calls.append(this_mock_call) if _new_parent._mock_new_name: if is_a_call: dot = '' else: dot = '.' is_a_call = _new_parent._mock_new_name == '()' mock_call_name = _new_parent._mock_new_name + dot + mock_call_name # follow the parental chain: _new_parent = _new_parent._mock_new_parent effect = self.side_effect if effect is not None: if _is_exception(effect): raise effect elif not _callable(effect): result = next(effect) if _is_exception(result): raise result else: result = effect(*args, **kwargs) if result is not DEFAULT: return result if self._mock_return_value is not DEFAULT: return self.return_value if self._mock_wraps is not None: return self._mock_wraps(*args, **kwargs) return self.return_value class Mock(CallableMixin, NonCallableMock): """ Create a new `Mock` object. `Mock` takes several optional arguments that specify the behaviour of the Mock object: * `spec`: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). Accessing any attribute not in this list will raise an `AttributeError`. If `spec` is an object (rather than a list of strings) then `mock.__class__` returns the class of the spec object. This allows mocks to pass `isinstance` tests. * `spec_set`: A stricter variant of `spec`. If used, attempting to *set* or get an attribute on the mock that isn't on the object passed as `spec_set` will raise an `AttributeError`. * `side_effect`: A function to be called whenever the Mock is called. See the `side_effect` attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns `DEFAULT`, the return value of this function is used as the return value. Alternatively `side_effect` can be an exception class or instance. In this case the exception will be raised when the mock is called. If `side_effect` is an iterable then each call to the mock will return the next value from the iterable. If any of the members of the iterable are exceptions they will be raised instead of returned. * `return_value`: The value returned when the mock is called. By default this is a new Mock (created on first access). See the `return_value` attribute. * `wraps`: Item for the mock object to wrap. If `wraps` is not None then calling the Mock will pass the call through to the wrapped object (returning the real result). Attribute access on the mock will return a Mock object that wraps the corresponding attribute of the wrapped object (so attempting to access an attribute that doesn't exist will raise an `AttributeError`). If the mock has an explicit `return_value` set then calls are not passed to the wrapped object and the `return_value` is returned instead. * `name`: If the mock has a name then it will be used in the repr of the mock. This can be useful for debugging. The name is propagated to child mocks. Mocks can also be called with arbitrary keyword arguments. These will be used to set attributes on the mock after it is created. """ def _dot_lookup(thing, comp, import_path): try: return getattr(thing, comp) except AttributeError: __import__(import_path) return getattr(thing, comp) def _importer(target): components = target.split('.') import_path = components.pop(0) thing = __import__(import_path) for comp in components: import_path += ".%s" % comp thing = _dot_lookup(thing, comp, import_path) return thing def _is_started(patcher): # XXXX horrible return hasattr(patcher, 'is_local') class _patch(object): attribute_name = None _active_patches = [] def __init__( self, getter, attribute, new, spec, create, spec_set, autospec, new_callable, kwargs ): if new_callable is not None: if new is not DEFAULT: raise ValueError( "Cannot use 'new' and 'new_callable' together" ) if autospec is not None: raise ValueError( "Cannot use 'autospec' and 'new_callable' together" ) self.getter = getter self.attribute = attribute self.new = new self.new_callable = new_callable self.spec = spec self.create = create self.has_local = False self.spec_set = spec_set self.autospec = autospec self.kwargs = kwargs self.additional_patchers = [] def copy(self): patcher = _patch( self.getter, self.attribute, self.new, self.spec, self.create, self.spec_set, self.autospec, self.new_callable, self.kwargs ) patcher.attribute_name = self.attribute_name patcher.additional_patchers = [ p.copy() for p in self.additional_patchers ] return patcher def __call__(self, func): if isinstance(func, ClassTypes): return self.decorate_class(func) return self.decorate_callable(func) def decorate_class(self, klass): for attr in dir(klass): if not attr.startswith(patch.TEST_PREFIX): continue attr_value = getattr(klass, attr) if not hasattr(attr_value, "__call__"): continue patcher = self.copy() setattr(klass, attr, patcher(attr_value)) return klass def decorate_callable(self, func): if hasattr(func, 'patchings'): func.patchings.append(self) return func @wraps(func) def patched(*args, **keywargs): extra_args = [] entered_patchers = [] exc_info = tuple() try: for patching in patched.patchings: arg = patching.__enter__() entered_patchers.append(patching) if patching.attribute_name is not None: keywargs.update(arg) elif patching.new is DEFAULT: extra_args.append(arg) args += tuple(extra_args) return func(*args, **keywargs) except: if (patching not in entered_patchers and _is_started(patching)): # the patcher may have been started, but an exception # raised whilst entering one of its additional_patchers entered_patchers.append(patching) # Pass the exception to __exit__ exc_info = sys.exc_info() # re-raise the exception raise finally: for patching in reversed(entered_patchers): patching.__exit__(*exc_info) patched.patchings = [self] return patched def get_original(self): target = self.getter() name = self.attribute original = DEFAULT local = False try: original = target.__dict__[name] except (AttributeError, KeyError): original = getattr(target, name, DEFAULT) else: local = True if name in _builtins and isinstance(target, ModuleType): self.create = True if not self.create and original is DEFAULT: raise AttributeError( "{} does not have the attribute {!r}".format(target, name) ) return original, local def __enter__(self): """Perform the patch.""" new, spec, spec_set = self.new, self.spec, self.spec_set autospec, kwargs = self.autospec, self.kwargs new_callable = self.new_callable self.target = self.getter() # normalise False to None if spec is False: spec = None if spec_set is False: spec_set = None if autospec is False: autospec = None if spec is not None and autospec is not None: raise TypeError("Can't specify spec and autospec") if ((spec is not None or autospec is not None) and spec_set not in (True, None)): raise TypeError("Can't provide explicit spec_set *and* spec or autospec") original, local = self.get_original() if new is DEFAULT and autospec is None: inherit = False if spec is True: # set spec to the object we are replacing spec = original if spec_set is True: spec_set = original spec = None elif spec is not None: if spec_set is True: spec_set = spec spec = None elif spec_set is True: spec_set = original if spec is not None or spec_set is not None: if original is DEFAULT: raise TypeError("Can't use 'spec' with create=True") if isinstance(original, ClassTypes): # If we're patching out a class and there is a spec inherit = True Klass = MagicMock _kwargs = {} if new_callable is not None: Klass = new_callable elif spec is not None or spec_set is not None: this_spec = spec if spec_set is not None: this_spec = spec_set if _is_list(this_spec): not_callable = '__call__' not in this_spec else: not_callable = not _callable(this_spec) if not_callable: Klass = NonCallableMagicMock if spec is not None: _kwargs['spec'] = spec if spec_set is not None: _kwargs['spec_set'] = spec_set # add a name to mocks if (isinstance(Klass, type) and issubclass(Klass, NonCallableMock) and self.attribute): _kwargs['name'] = self.attribute _kwargs.update(kwargs) new = Klass(**_kwargs) if inherit and _is_instance_mock(new): # we can only tell if the instance should be callable if the # spec is not a list this_spec = spec if spec_set is not None: this_spec = spec_set if (not _is_list(this_spec) and not _instance_callable(this_spec)): Klass = NonCallableMagicMock _kwargs.pop('name') new.return_value = Klass(_new_parent=new, _new_name='()', **_kwargs) elif autospec is not None: # spec is ignored, new *must* be default, spec_set is treated # as a boolean. Should we check spec is not None and that spec_set # is a bool? if new is not DEFAULT: raise TypeError( "autospec creates the mock for you. Can't specify " "autospec and new." ) if original is DEFAULT: raise TypeError("Can't use 'autospec' with create=True") spec_set = bool(spec_set) if autospec is True: autospec = original new = create_autospec(autospec, spec_set=spec_set, _name=self.attribute, **kwargs) elif kwargs: # can't set keyword args when we aren't creating the mock # XXXX If new is a Mock we could call new.configure_mock(**kwargs) raise TypeError("Can't pass kwargs to a mock we aren't creating") new_attr = new self.temp_original = original self.is_local = local setattr(self.target, self.attribute, new_attr) if self.attribute_name is not None: extra_args = {} if self.new is DEFAULT: extra_args[self.attribute_name] = new for patching in self.additional_patchers: arg = patching.__enter__() if patching.new is DEFAULT: extra_args.update(arg) return extra_args return new def __exit__(self, *exc_info): """Undo the patch.""" if not _is_started(self): return if self.is_local and self.temp_original is not DEFAULT: setattr(self.target, self.attribute, self.temp_original) else: delattr(self.target, self.attribute) if not self.create and (not hasattr(self.target, self.attribute) or self.attribute in ('__doc__', '__module__', '__defaults__', '__annotations__', '__kwdefaults__')): # needed for proxy objects like django settings setattr(self.target, self.attribute, self.temp_original) del self.temp_original del self.is_local del self.target for patcher in reversed(self.additional_patchers): if _is_started(patcher): patcher.__exit__(*exc_info) def start(self): """Activate a patch, returning any created mock.""" result = self.__enter__() self._active_patches.append(self) return result def stop(self): """Stop an active patch.""" try: self._active_patches.remove(self) except ValueError: # If the patch hasn't been started this will fail pass return self.__exit__() def _get_target(target): try: target, attribute = target.rsplit('.', 1) except (TypeError, ValueError): raise TypeError("Need a valid target to patch. You supplied: %r" % (target,)) getter = lambda: _importer(target) return getter, attribute def _patch_object( target, attribute, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs ): """ patch the named member (`attribute`) on an object (`target`) with a mock object. `patch.object` can be used as a decorator, class decorator or a context manager. Arguments `new`, `spec`, `create`, `spec_set`, `autospec` and `new_callable` have the same meaning as for `patch`. Like `patch`, `patch.object` takes arbitrary keyword arguments for configuring the mock object it creates. When used as a class decorator `patch.object` honours `patch.TEST_PREFIX` for choosing which methods to wrap. """ getter = lambda: target return _patch( getter, attribute, new, spec, create, spec_set, autospec, new_callable, kwargs ) def _patch_multiple(target, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs): """Perform multiple patches in a single call. It takes the object to be patched (either as an object or a string to fetch the object by importing) and keyword arguments for the patches:: with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'): ... Use `DEFAULT` as the value if you want `patch.multiple` to create mocks for you. In this case the created mocks are passed into a decorated function by keyword, and a dictionary is returned when `patch.multiple` is used as a context manager. `patch.multiple` can be used as a decorator, class decorator or a context manager. The arguments `spec`, `spec_set`, `create`, `autospec` and `new_callable` have the same meaning as for `patch`. These arguments will be applied to *all* patches done by `patch.multiple`. When used as a class decorator `patch.multiple` honours `patch.TEST_PREFIX` for choosing which methods to wrap. """ if type(target) in (unicode, str): getter = lambda: _importer(target) else: getter = lambda: target if not kwargs: raise ValueError( 'Must supply at least one keyword argument with patch.multiple' ) # need to wrap in a list for python 3, where items is a view items = list(kwargs.items()) attribute, new = items[0] patcher = _patch( getter, attribute, new, spec, create, spec_set, autospec, new_callable, {} ) patcher.attribute_name = attribute for attribute, new in items[1:]: this_patcher = _patch( getter, attribute, new, spec, create, spec_set, autospec, new_callable, {} ) this_patcher.attribute_name = attribute patcher.additional_patchers.append(this_patcher) return patcher def patch( target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs ): """ `patch` acts as a function decorator, class decorator or a context manager. Inside the body of the function or with statement, the `target` is patched with a `new` object. When the function/with statement exits the patch is undone. If `new` is omitted, then the target is replaced with a `MagicMock`. If `patch` is used as a decorator and `new` is omitted, the created mock is passed in as an extra argument to the decorated function. If `patch` is used as a context manager the created mock is returned by the context manager. `target` should be a string in the form `'package.module.ClassName'`. The `target` is imported and the specified object replaced with the `new` object, so the `target` must be importable from the environment you are calling `patch` from. The target is imported when the decorated function is executed, not at decoration time. The `spec` and `spec_set` keyword arguments are passed to the `MagicMock` if patch is creating one for you. In addition you can pass `spec=True` or `spec_set=True`, which causes patch to pass in the object being mocked as the spec/spec_set object. `new_callable` allows you to specify a different class, or callable object, that will be called to create the `new` object. By default `MagicMock` is used. A more powerful form of `spec` is `autospec`. If you set `autospec=True` then the mock will be created with a spec from the object being replaced. All attributes of the mock will also have the spec of the corresponding attribute of the object being replaced. Methods and functions being mocked will have their arguments checked and will raise a `TypeError` if they are called with the wrong signature. For mocks replacing a class, their return value (the 'instance') will have the same spec as the class. Instead of `autospec=True` you can pass `autospec=some_object` to use an arbitrary object as the spec instead of the one being replaced. By default `patch` will fail to replace attributes that don't exist. If you pass in `create=True`, and the attribute doesn't exist, patch will create the attribute for you when the patched function is called, and delete it again afterwards. This is useful for writing tests against attributes that your production code creates at runtime. It is off by default because it can be dangerous. With it switched on you can write passing tests against APIs that don't actually exist! Patch can be used as a `TestCase` class decorator. It works by decorating each test method in the class. This reduces the boilerplate code when your test methods share a common patchings set. `patch` finds tests by looking for method names that start with `patch.TEST_PREFIX`. By default this is `test`, which matches the way `unittest` finds tests. You can specify an alternative prefix by setting `patch.TEST_PREFIX`. Patch can be used as a context manager, with the with statement. Here the patching applies to the indented block after the with statement. If you use "as" then the patched object will be bound to the name after the "as"; very useful if `patch` is creating a mock object for you. `patch` takes arbitrary keyword arguments. These will be passed to the `Mock` (or `new_callable`) on construction. `patch.dict(...)`, `patch.multiple(...)` and `patch.object(...)` are available for alternate use-cases. """ getter, attribute = _get_target(target) return _patch( getter, attribute, new, spec, create, spec_set, autospec, new_callable, kwargs ) class _patch_dict(object): """ Patch a dictionary, or dictionary like object, and restore the dictionary to its original state after the test. `in_dict` can be a dictionary or a mapping like container. If it is a mapping then it must at least support getting, setting and deleting items plus iterating over keys. `in_dict` can also be a string specifying the name of the dictionary, which will then be fetched by importing it. `values` can be a dictionary of values to set in the dictionary. `values` can also be an iterable of `(key, value)` pairs. If `clear` is True then the dictionary will be cleared before the new values are set. `patch.dict` can also be called with arbitrary keyword arguments to set values in the dictionary:: with patch.dict('sys.modules', mymodule=Mock(), other_module=Mock()): ... `patch.dict` can be used as a context manager, decorator or class decorator. When used as a class decorator `patch.dict` honours `patch.TEST_PREFIX` for choosing which methods to wrap. """ def __init__(self, in_dict, values=(), clear=False, **kwargs): self.in_dict = in_dict # support any argument supported by dict(...) constructor self.values = dict(values) self.values.update(kwargs) self.clear = clear self._original = None def __call__(self, f): if isinstance(f, ClassTypes): return self.decorate_class(f) @wraps(f) def _inner(*args, **kw): self._patch_dict() try: return f(*args, **kw) finally: self._unpatch_dict() return _inner def decorate_class(self, klass): for attr in dir(klass): attr_value = getattr(klass, attr) if (attr.startswith(patch.TEST_PREFIX) and hasattr(attr_value, "__call__")): decorator = _patch_dict(self.in_dict, self.values, self.clear) decorated = decorator(attr_value) setattr(klass, attr, decorated) return klass def __enter__(self): """Patch the dict.""" self._patch_dict() def _patch_dict(self): values = self.values if isinstance(self.in_dict, basestring): self.in_dict = _importer(self.in_dict) in_dict = self.in_dict clear = self.clear try: original = in_dict.copy() except AttributeError: # dict like object with no copy method # must support iteration over keys original = {} for key in in_dict: original[key] = in_dict[key] self._original = original if clear: _clear_dict(in_dict) try: in_dict.update(values) except AttributeError: # dict like object with no update method for key in values: in_dict[key] = values[key] def _unpatch_dict(self): in_dict = self.in_dict original = self._original _clear_dict(in_dict) try: in_dict.update(original) except AttributeError: for key in original: in_dict[key] = original[key] def __exit__(self, *args): """Unpatch the dict.""" self._unpatch_dict() return False start = __enter__ stop = __exit__ def _clear_dict(in_dict): try: in_dict.clear() except AttributeError: keys = list(in_dict) for key in keys: del in_dict[key] def _patch_stopall(): """Stop all active patches. LIFO to unroll nested patches.""" for patch in reversed(_patch._active_patches): patch.stop() patch.object = _patch_object patch.dict = _patch_dict patch.multiple = _patch_multiple patch.stopall = _patch_stopall patch.TEST_PREFIX = 'test' magic_methods = ( "lt le gt ge eq ne " "getitem setitem delitem " "len contains iter " "hash str sizeof " "enter exit " # we added divmod and rdivmod here instead of numerics # because there is no idivmod "divmod rdivmod neg pos abs invert " "complex int float index " "round trunc floor ceil " ) numerics = ( "add sub mul matmul div floordiv mod lshift rshift and xor or pow" ) if six.PY3: numerics += ' truediv' inplace = ' '.join('i%s' % n for n in numerics.split()) right = ' '.join('r%s' % n for n in numerics.split()) extra = '' if six.PY3: extra = 'bool next ' if sys.version_info >= (3, 6): extra += 'fspath ' else: extra = 'unicode long nonzero oct hex truediv rtruediv ' # not including __prepare__, __instancecheck__, __subclasscheck__ # (as they are metaclass methods) # __del__ is not supported at all as it causes problems if it exists _non_defaults = { '__cmp__', '__getslice__', '__setslice__', '__coerce__', # <3.x '__get__', '__set__', '__delete__', '__reversed__', '__missing__', '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', '__getstate__', '__setstate__', '__getformat__', '__setformat__', '__repr__', '__dir__', '__subclasses__', '__format__', '__getnewargs_ex__', } def _get_method(name, func): "Turns a callable object (like a mock) into a real function" def method(self, *args, **kw): return func(self, *args, **kw) method.__name__ = name return method _magics = { '__%s__' % method for method in ' '.join([magic_methods, numerics, inplace, right, extra]).split() } _all_magics = _magics | _non_defaults _unsupported_magics = { '__getattr__', '__setattr__', '__init__', '__new__', '__prepare__', '__instancecheck__', '__subclasscheck__', '__del__' } _calculate_return_value = { '__hash__': lambda self: object.__hash__(self), '__str__': lambda self: object.__str__(self), '__sizeof__': lambda self: object.__sizeof__(self), '__unicode__': lambda self: unicode(object.__str__(self)), '__fspath__': lambda self: type(self).__name__+'/'+self._extract_mock_name()+'/'+str(id(self)), } _return_values = { '__lt__': NotImplemented, '__gt__': NotImplemented, '__le__': NotImplemented, '__ge__': NotImplemented, '__int__': 1, '__contains__': False, '__len__': 0, '__exit__': False, '__complex__': 1j, '__float__': 1.0, '__bool__': True, '__nonzero__': True, '__oct__': '1', '__hex__': '0x1', '__long__': long(1), '__index__': 1, } def _get_eq(self): def __eq__(other): ret_val = self.__eq__._mock_return_value if ret_val is not DEFAULT: return ret_val if self is other: return True return NotImplemented return __eq__ def _get_ne(self): def __ne__(other): if self.__ne__._mock_return_value is not DEFAULT: return DEFAULT if self is other: return False return NotImplemented return __ne__ def _get_iter(self): def __iter__(): ret_val = self.__iter__._mock_return_value if ret_val is DEFAULT: return iter([]) # if ret_val was already an iterator, then calling iter on it should # return the iterator unchanged return iter(ret_val) return __iter__ _side_effect_methods = { '__eq__': _get_eq, '__ne__': _get_ne, '__iter__': _get_iter, } def _set_return_value(mock, method, name): fixed = _return_values.get(name, DEFAULT) if fixed is not DEFAULT: method.return_value = fixed return return_calulator = _calculate_return_value.get(name) if return_calulator is not None: try: return_value = return_calulator(mock) except AttributeError: # XXXX why do we return AttributeError here? # set it as a side_effect instead? # Answer: it makes magic mocks work on pypy?! return_value = AttributeError(name) method.return_value = return_value return side_effector = _side_effect_methods.get(name) if side_effector is not None: method.side_effect = side_effector(mock) class MagicMixin(object): def __init__(self, *args, **kw): self._mock_set_magics() # make magic work for kwargs in init _safe_super(MagicMixin, self).__init__(*args, **kw) self._mock_set_magics() # fix magic broken by upper level init def _mock_set_magics(self): these_magics = _magics if getattr(self, "_mock_methods", None) is not None: these_magics = _magics.intersection(self._mock_methods) remove_magics = set() remove_magics = _magics - these_magics for entry in remove_magics: if entry in type(self).__dict__: # remove unneeded magic methods delattr(self, entry) # don't overwrite existing attributes if called a second time these_magics = these_magics - set(type(self).__dict__) _type = type(self) for entry in these_magics: setattr(_type, entry, MagicProxy(entry, self)) class NonCallableMagicMock(MagicMixin, NonCallableMock): """A version of `MagicMock` that isn't callable.""" def mock_add_spec(self, spec, spec_set=False): """Add a spec to a mock. `spec` can either be an object or a list of strings. Only attributes on the `spec` can be fetched as attributes from the mock. If `spec_set` is True then only attributes on the spec can be set.""" self._mock_add_spec(spec, spec_set) self._mock_set_magics() class MagicMock(MagicMixin, Mock): """ MagicMock is a subclass of Mock with default implementations of most of the magic methods. You can use MagicMock without having to configure the magic methods yourself. If you use the `spec` or `spec_set` arguments then *only* magic methods that exist in the spec will be created. Attributes and the return value of a `MagicMock` will also be `MagicMocks`. """ def mock_add_spec(self, spec, spec_set=False): """Add a spec to a mock. `spec` can either be an object or a list of strings. Only attributes on the `spec` can be fetched as attributes from the mock. If `spec_set` is True then only attributes on the spec can be set.""" self._mock_add_spec(spec, spec_set) self._mock_set_magics() class MagicProxy(object): def __init__(self, name, parent): self.name = name self.parent = parent def create_mock(self): entry = self.name parent = self.parent m = parent._get_child_mock(name=entry, _new_name=entry, _new_parent=parent) setattr(parent, entry, m) _set_return_value(parent, m, entry) return m def __get__(self, obj, _type=None): return self.create_mock() class _ANY(object): "A helper object that compares equal to everything." def __eq__(self, other): return True def __ne__(self, other): return False def __repr__(self): return '' __hash__ = None ANY = _ANY() def _format_call_signature(name, args, kwargs): message = '%s(%%s)' % name formatted_args = '' args_string = ', '.join([repr(arg) for arg in args]) def encode_item(item): if six.PY2 and isinstance(item, unicode): return item.encode("utf-8") else: return item kwargs_string = ', '.join([ '{}={!r}'.format(encode_item(key), value) for key, value in sorted(kwargs.items()) ]) if args_string: formatted_args = args_string if kwargs_string: if formatted_args: formatted_args += ', ' formatted_args += kwargs_string return message % formatted_args class _Call(tuple): """ A tuple for holding the results of a call to a mock, either in the form `(args, kwargs)` or `(name, args, kwargs)`. If args or kwargs are empty then a call tuple will compare equal to a tuple without those values. This makes comparisons less verbose:: _Call(('name', (), {})) == ('name',) _Call(('name', (1,), {})) == ('name', (1,)) _Call(((), {'a': 'b'})) == ({'a': 'b'},) The `_Call` object provides a useful shortcut for comparing with call:: _Call(((1, 2), {'a': 3})) == call(1, 2, a=3) _Call(('foo', (1, 2), {'a': 3})) == call.foo(1, 2, a=3) If the _Call has no name then it will match any name. """ def __new__(cls, value=(), name='', parent=None, two=False, from_kall=True): args = () kwargs = {} _len = len(value) if _len == 3: name, args, kwargs = value elif _len == 2: first, second = value if isinstance(first, basestring): name = first if isinstance(second, tuple): args = second else: kwargs = second else: args, kwargs = first, second elif _len == 1: value, = value if isinstance(value, basestring): name = value elif isinstance(value, tuple): args = value else: kwargs = value if two: return tuple.__new__(cls, (args, kwargs)) return tuple.__new__(cls, (name, args, kwargs)) def __init__(self, value=(), name=None, parent=None, two=False, from_kall=True): self._mock_name = name self._mock_parent = parent self._mock_from_kall = from_kall def __eq__(self, other): if other is ANY: return True try: len_other = len(other) except TypeError: return False self_name = '' if len(self) == 2: self_args, self_kwargs = self else: self_name, self_args, self_kwargs = self if (getattr(self, '_mock_parent', None) and getattr(other, '_mock_parent', None) and self._mock_parent != other._mock_parent): return False other_name = '' if len_other == 0: other_args, other_kwargs = (), {} elif len_other == 3: other_name, other_args, other_kwargs = other elif len_other == 1: value, = other if isinstance(value, tuple): other_args = value other_kwargs = {} elif isinstance(value, basestring): other_name = value other_args, other_kwargs = (), {} else: other_args = () other_kwargs = value elif len_other == 2: # could be (name, args) or (name, kwargs) or (args, kwargs) first, second = other if isinstance(first, basestring): other_name = first if isinstance(second, tuple): other_args, other_kwargs = second, {} else: other_args, other_kwargs = (), second else: other_args, other_kwargs = first, second else: return False if self_name and other_name != self_name: return False # this order is important for ANY to work! return (other_args, other_kwargs) == (self_args, self_kwargs) def __ne__(self, other): return not self.__eq__(other) __hash__ = None def __call__(self, *args, **kwargs): if self._mock_name is None: return _Call(('', args, kwargs), name='()') name = self._mock_name + '()' return _Call((self._mock_name, args, kwargs), name=name, parent=self) def __getattr__(self, attr): if self._mock_name is None: return _Call(name=attr, from_kall=False) name = '{}.{}'.format(self._mock_name, attr) return _Call(name=name, parent=self, from_kall=False) def count(self, *args, **kwargs): return self.__getattr__('count')(*args, **kwargs) def index(self, *args, **kwargs): return self.__getattr__('index')(*args, **kwargs) def _get_call_arguments(self): if len(self) == 2: args, kwargs = self else: name, args, kwargs = self return args, kwargs @property def args(self): return self._get_call_arguments()[0] @property def kwargs(self): return self._get_call_arguments()[1] def __repr__(self): if not self._mock_from_kall: name = self._mock_name or 'call' if name.startswith('()'): name = 'call%s' % name return name if len(self) == 2: name = 'call' args, kwargs = self else: name, args, kwargs = self if not name: name = 'call' elif not name.startswith('()'): name = 'call.%s' % name else: name = 'call%s' % name return _format_call_signature(name, args, kwargs) def call_list(self): """For a call object that represents multiple calls, `call_list` returns a list of all the intermediate calls as well as the final call.""" vals = [] thing = self while thing is not None: if thing._mock_from_kall: vals.append(thing) thing = thing._mock_parent return _CallList(reversed(vals)) call = _Call(from_kall=False) def create_autospec(spec, spec_set=False, instance=False, _parent=None, _name=None, **kwargs): """Create a mock object using another object as a spec. Attributes on the mock will use the corresponding attribute on the `spec` object as their spec. Functions or methods being mocked will have their arguments checked to check that they are called with the correct signature. If `spec_set` is True then attempting to set attributes that don't exist on the spec object will raise an `AttributeError`. If a class is used as a spec then the return value of the mock (the instance of the class) will have the same spec. You can use a class as the spec for an instance object by passing `instance=True`. The returned mock will only be callable if instances of the mock are callable. `create_autospec` also takes arbitrary keyword arguments that are passed to the constructor of the created mock.""" if _is_list(spec): # can't pass a list instance to the mock constructor as it will be # interpreted as a list of strings spec = type(spec) is_type = isinstance(spec, ClassTypes) _kwargs = {'spec': spec} if spec_set: _kwargs = {'spec_set': spec} elif spec is None: # None we mock with a normal mock without a spec _kwargs = {} if _kwargs and instance: _kwargs['_spec_as_instance'] = True _kwargs.update(kwargs) Klass = MagicMock if inspect.isdatadescriptor(spec): # descriptors don't have a spec # because we don't know what type they return _kwargs = {} elif not _callable(spec): Klass = NonCallableMagicMock elif is_type and instance and not _instance_callable(spec): Klass = NonCallableMagicMock _name = _kwargs.pop('name', _name) _new_name = _name if _parent is None: # for a top level object no _new_name should be set _new_name = '' mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name, name=_name, **_kwargs) if isinstance(spec, FunctionTypes): # should only happen at the top level because we don't # recurse for functions mock = _set_signature(mock, spec) else: _check_signature(spec, mock, is_type, instance) if _parent is not None and not instance: _parent._mock_children[_name] = mock if is_type and not instance and 'return_value' not in kwargs: mock.return_value = create_autospec(spec, spec_set, instance=True, _name='()', _parent=mock) for entry in dir(spec): # This are __ and so treated as magic on Py3, on Py2 we need to # explicitly ignore them: if six.PY2 and (entry.startswith('im_') or entry.startswith('func_')): continue if _is_magic(entry): # MagicMock already does the useful magic methods for us continue # XXXX do we need a better way of getting attributes without # triggering code execution (?) Probably not - we need the actual # object to mock it so we would rather trigger a property than mock # the property descriptor. Likewise we want to mock out dynamically # provided attributes. # XXXX what about attributes that raise exceptions other than # AttributeError on being fetched? # we could be resilient against it, or catch and propagate the # exception when the attribute is fetched from the mock try: original = getattr(spec, entry) except AttributeError: continue kwargs = {'spec': original} if spec_set: kwargs = {'spec_set': original} if not isinstance(original, FunctionTypes): new = _SpecState(original, spec_set, mock, entry, instance) mock._mock_children[entry] = new else: parent = mock if isinstance(spec, FunctionTypes): parent = mock.mock skipfirst = _must_skip(spec, entry, is_type) kwargs['_eat_self'] = skipfirst new = MagicMock(parent=parent, name=entry, _new_name=entry, _new_parent=parent, **kwargs) mock._mock_children[entry] = new _check_signature(original, new, skipfirst=skipfirst) # so functions created with _set_signature become instance attributes, # *plus* their underlying mock exists in _mock_children of the parent # mock. Adding to _mock_children may be unnecessary where we are also # setting as an instance attribute? if isinstance(new, FunctionTypes): setattr(mock, entry, new) return mock def _must_skip(spec, entry, is_type): """ Return whether we should skip the first argument on spec's `entry` attribute. """ if not isinstance(spec, ClassTypes): if entry in getattr(spec, '__dict__', {}): # instance attribute - shouldn't skip return False spec = spec.__class__ if not hasattr(spec, '__mro__'): # old style class: can't have descriptors anyway return is_type for klass in spec.__mro__: result = klass.__dict__.get(entry, DEFAULT) if result is DEFAULT: continue if isinstance(result, (staticmethod, classmethod)): return False elif isinstance(getattr(result, '__get__', None), MethodWrapperTypes): # Normal method => skip if looked up on type # (if looked up on instance, self is already skipped) return is_type else: return False # function is a dynamically provided attribute return is_type class _SpecState(object): def __init__(self, spec, spec_set=False, parent=None, name=None, ids=None, instance=False): self.spec = spec self.ids = ids self.spec_set = spec_set self.parent = parent self.instance = instance self.name = name FunctionTypes = ( # python function type(create_autospec), # instance method type(ANY.__eq__), ) MethodWrapperTypes = ( type(ANY.__eq__.__get__), ) file_spec = None def _to_stream(read_data): if isinstance(read_data, bytes): return io.BytesIO(read_data) else: return io.StringIO(read_data) def mock_open(mock=None, read_data=''): """ A helper function to create a mock to replace the use of `open`. It works for `open` called directly or used as a context manager. The `mock` argument is the mock object to configure. If `None` (the default) then a `MagicMock` will be created for you, with the API limited to methods or attributes available on standard file handles. `read_data` is a string for the `read`, `readline` and `readlines` of the file handle to return. This is an empty string by default. """ _read_data = _to_stream(read_data) _state = [_read_data, None] def _readlines_side_effect(*args, **kwargs): if handle.readlines.return_value is not None: return handle.readlines.return_value return _state[0].readlines(*args, **kwargs) def _read_side_effect(*args, **kwargs): if handle.read.return_value is not None: return handle.read.return_value return _state[0].read(*args, **kwargs) def _readline_side_effect(*args, **kwargs): for item in _iter_side_effect(): yield item while True: yield _state[0].readline(*args, **kwargs) def _iter_side_effect(): if handle.readline.return_value is not None: while True: yield handle.readline.return_value for line in _state[0]: yield line global file_spec if file_spec is None: # set on first use if six.PY3: import _io file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) else: file_spec = file if mock is None: mock = MagicMock(name='open', spec=open) handle = MagicMock(spec=file_spec) handle.__enter__.return_value = handle handle.write.return_value = None handle.read.return_value = None handle.readline.return_value = None handle.readlines.return_value = None handle.read.side_effect = _read_side_effect _state[1] = _readline_side_effect() handle.readline.side_effect = _state[1] handle.readlines.side_effect = _readlines_side_effect handle.__iter__.side_effect = _iter_side_effect def reset_data(*args, **kwargs): _state[0] = _to_stream(read_data) if handle.readline.side_effect == _state[1]: # Only reset the side effect if the user hasn't overridden it. _state[1] = _readline_side_effect() handle.readline.side_effect = _state[1] return DEFAULT mock.side_effect = reset_data mock.return_value = handle return mock class PropertyMock(Mock): """ A mock intended to be used as a property, or other descriptor, on a class. `PropertyMock` provides `__get__` and `__set__` methods so you can specify a return value when it is fetched. Fetching a `PropertyMock` instance from an object calls the mock, with no args. Setting it calls the mock with the value being set. """ def _get_child_mock(self, **kwargs): return MagicMock(**kwargs) def __get__(self, obj, obj_type): return self() def __set__(self, obj, val): self(val) def seal(mock): """Disable the automatic generation of child mocks. Given an input Mock, seals it to ensure no further mocks will be generated when accessing an attribute that was not already defined. The operation recursively seals the mock passed in, meaning that the mock itself, any mocks generated by accessing one of its attributes, and all assigned mocks without a name or spec will be sealed. """ mock._mock_sealed = True for attr in dir(mock): try: m = getattr(mock, attr) except AttributeError: continue if not isinstance(m, NonCallableMock): continue if m._mock_new_parent is mock: seal(m) mock-3.0.5/mock/tests/000077500000000000000000000000001346437275100145575ustar00rootroot00000000000000mock-3.0.5/mock/tests/__init__.py000066400000000000000000000002221346437275100166640ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ mock-3.0.5/mock/tests/__main__.py000066400000000000000000000011571346437275100166550ustar00rootroot00000000000000import os import unittest def load_tests(loader, standard_tests, pattern): # top level directory cached on loader instance this_dir = os.path.dirname(__file__) pattern = pattern or "test*.py" # We are inside unittest.test.testmock, so the top-level is three notches up top_level_dir = os.path.dirname(os.path.dirname(os.path.dirname(this_dir))) package_tests = loader.discover(start_dir=this_dir, pattern=pattern, top_level_dir=top_level_dir) standard_tests.addTests(package_tests) return standard_tests if __name__ == '__main__': unittest.main() mock-3.0.5/mock/tests/conftest.py000066400000000000000000000001551346437275100167570ustar00rootroot00000000000000import six def pytest_ignore_collect(path): if 'py3' in path.basename and six.PY2: return True mock-3.0.5/mock/tests/support.py000066400000000000000000000016311346437275100166460ustar00rootroot00000000000000import contextlib import sys target = {'foo': 'FOO'} def is_instance(obj, klass): """Version of is_instance that doesn't access __class__""" return issubclass(type(obj), klass) class SomeClass(object): class_attribute = None def wibble(self): pass class X(object): pass @contextlib.contextmanager def uncache(*names): """Uncache a module from sys.modules. A basic sanity check is performed to prevent uncaching modules that either cannot/shouldn't be uncached. """ for name in names: if name in ('sys', 'marshal', 'imp'): raise ValueError( "cannot uncache {0}".format(name)) try: del sys.modules[name] except KeyError: pass try: yield finally: for name in names: try: del sys.modules[name] except KeyError: pass mock-3.0.5/mock/tests/testcallable.py000066400000000000000000000104421346437275100175710ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ import unittest from mock.tests.support import is_instance, X, SomeClass from mock import ( Mock, MagicMock, NonCallableMagicMock, NonCallableMock, patch, create_autospec, CallableMixin ) class TestCallable(unittest.TestCase): def assertNotCallable(self, mock): self.assertTrue(is_instance(mock, NonCallableMagicMock)) self.assertFalse(is_instance(mock, CallableMixin)) def test_non_callable(self): for mock in NonCallableMagicMock(), NonCallableMock(): self.assertRaises(TypeError, mock) self.assertFalse(hasattr(mock, '__call__')) self.assertIn(mock.__class__.__name__, repr(mock)) def test_hierarchy(self): self.assertTrue(issubclass(MagicMock, Mock)) self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock)) def test_attributes(self): one = NonCallableMock() self.assertTrue(issubclass(type(one.one), Mock)) two = NonCallableMagicMock() self.assertTrue(issubclass(type(two.two), MagicMock)) def test_subclasses(self): class MockSub(Mock): pass one = MockSub() self.assertTrue(issubclass(type(one.one), MockSub)) class MagicSub(MagicMock): pass two = MagicSub() self.assertTrue(issubclass(type(two.two), MagicSub)) def test_patch_spec(self): patcher = patch('%s.X' % __name__, spec=True) mock = patcher.start() self.addCleanup(patcher.stop) instance = mock() mock.assert_called_once_with() self.assertNotCallable(instance) self.assertRaises(TypeError, instance) def test_patch_spec_set(self): patcher = patch('%s.X' % __name__, spec_set=True) mock = patcher.start() self.addCleanup(patcher.stop) instance = mock() mock.assert_called_once_with() self.assertNotCallable(instance) self.assertRaises(TypeError, instance) def test_patch_spec_instance(self): patcher = patch('%s.X' % __name__, spec=X()) mock = patcher.start() self.addCleanup(patcher.stop) self.assertNotCallable(mock) self.assertRaises(TypeError, mock) def test_patch_spec_set_instance(self): patcher = patch('%s.X' % __name__, spec_set=X()) mock = patcher.start() self.addCleanup(patcher.stop) self.assertNotCallable(mock) self.assertRaises(TypeError, mock) def test_patch_spec_callable_class(self): class CallableX(X): def __call__(self): pass class Sub(CallableX): pass class Multi(SomeClass, Sub): pass class OldStyle: def __call__(self): pass class OldStyleSub(OldStyle): pass for arg in 'spec', 'spec_set': for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub: with patch('%s.X' % __name__, **{arg: Klass}) as mock: instance = mock() mock.assert_called_once_with() self.assertTrue(is_instance(instance, MagicMock)) # inherited spec self.assertRaises(AttributeError, getattr, instance, 'foobarbaz') result = instance() # instance is callable, result has no spec instance.assert_called_once_with() result(3, 2, 1) result.assert_called_once_with(3, 2, 1) result.foo(3, 2, 1) result.foo.assert_called_once_with(3, 2, 1) def test_create_autospec(self): mock = create_autospec(X) instance = mock() self.assertRaises(TypeError, instance) mock = create_autospec(X()) self.assertRaises(TypeError, mock) def test_create_autospec_instance(self): mock = create_autospec(SomeClass, instance=True) self.assertRaises(TypeError, mock) mock.wibble() mock.wibble.assert_called_once_with() self.assertRaises(TypeError, mock.wibble, 'some', 'args') if __name__ == "__main__": unittest.main() mock-3.0.5/mock/tests/testhelpers.py000066400000000000000000001060621346437275100175000ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ import socket import inspect import six import sys import time import unittest from mock import ( call, create_autospec, MagicMock, Mock, ANY, patch, PropertyMock ) from mock.mock import _Call, _CallList, _callable from datetime import datetime from functools import partial if six.PY2: import funcsigs class SomeClass(object): def one(self, a, b): pass def two(self): pass def three(self, a=None): pass class AnyTest(unittest.TestCase): def test_any(self): self.assertEqual(ANY, object()) mock = Mock() mock(ANY) mock.assert_called_with(ANY) mock = Mock() mock(foo=ANY) mock.assert_called_with(foo=ANY) def test_repr(self): self.assertEqual(repr(ANY), '') self.assertEqual(str(ANY), '') def test_any_and_datetime(self): mock = Mock() mock(datetime.now(), foo=datetime.now()) mock.assert_called_with(ANY, foo=ANY) def test_any_mock_calls_comparison_order(self): mock = Mock() class Foo(object): def __eq__(self, other): pass def __ne__(self, other): pass for d in datetime.now(), Foo(): mock.reset_mock() mock(d, foo=d, bar=d) mock.method(d, zinga=d, alpha=d) mock().method(a1=d, z99=d) expected = [ call(ANY, foo=ANY, bar=ANY), call.method(ANY, zinga=ANY, alpha=ANY), call(), call().method(a1=ANY, z99=ANY) ] self.assertEqual(expected, mock.mock_calls) self.assertEqual(mock.mock_calls, expected) class CallTest(unittest.TestCase): def test_call_with_call(self): kall = _Call() self.assertEqual(kall, _Call()) self.assertEqual(kall, _Call(('',))) self.assertEqual(kall, _Call(((),))) self.assertEqual(kall, _Call(({},))) self.assertEqual(kall, _Call(('', ()))) self.assertEqual(kall, _Call(('', {}))) self.assertEqual(kall, _Call(('', (), {}))) self.assertEqual(kall, _Call(('foo',))) self.assertEqual(kall, _Call(('bar', ()))) self.assertEqual(kall, _Call(('baz', {}))) self.assertEqual(kall, _Call(('spam', (), {}))) kall = _Call(((1, 2, 3),)) self.assertEqual(kall, _Call(((1, 2, 3),))) self.assertEqual(kall, _Call(('', (1, 2, 3)))) self.assertEqual(kall, _Call(((1, 2, 3), {}))) self.assertEqual(kall, _Call(('', (1, 2, 3), {}))) kall = _Call(((1, 2, 4),)) self.assertNotEqual(kall, _Call(('', (1, 2, 3)))) self.assertNotEqual(kall, _Call(('', (1, 2, 3), {}))) kall = _Call(('foo', (1, 2, 4),)) self.assertNotEqual(kall, _Call(('', (1, 2, 4)))) self.assertNotEqual(kall, _Call(('', (1, 2, 4), {}))) self.assertNotEqual(kall, _Call(('bar', (1, 2, 4)))) self.assertNotEqual(kall, _Call(('bar', (1, 2, 4), {}))) kall = _Call(({'a': 3},)) self.assertEqual(kall, _Call(('', (), {'a': 3}))) self.assertEqual(kall, _Call(('', {'a': 3}))) self.assertEqual(kall, _Call(((), {'a': 3}))) self.assertEqual(kall, _Call(({'a': 3},))) def test_empty__Call(self): args = _Call() self.assertEqual(args, ()) self.assertEqual(args, ('foo',)) self.assertEqual(args, ((),)) self.assertEqual(args, ('foo', ())) self.assertEqual(args, ('foo',(), {})) self.assertEqual(args, ('foo', {})) self.assertEqual(args, ({},)) def test_named_empty_call(self): args = _Call(('foo', (), {})) self.assertEqual(args, ('foo',)) self.assertEqual(args, ('foo', ())) self.assertEqual(args, ('foo',(), {})) self.assertEqual(args, ('foo', {})) self.assertNotEqual(args, ((),)) self.assertNotEqual(args, ()) self.assertNotEqual(args, ({},)) self.assertNotEqual(args, ('bar',)) self.assertNotEqual(args, ('bar', ())) self.assertNotEqual(args, ('bar', {})) def test_call_with_args(self): args = _Call(((1, 2, 3), {})) self.assertEqual(args, ((1, 2, 3),)) self.assertEqual(args, ('foo', (1, 2, 3))) self.assertEqual(args, ('foo', (1, 2, 3), {})) self.assertEqual(args, ((1, 2, 3), {})) self.assertEqual(args.args, (1, 2, 3)) self.assertEqual(args.kwargs, {}) def test_named_call_with_args(self): args = _Call(('foo', (1, 2, 3), {})) self.assertEqual(args, ('foo', (1, 2, 3))) self.assertEqual(args, ('foo', (1, 2, 3), {})) self.assertEqual(args.args, (1, 2, 3)) self.assertEqual(args.kwargs, {}) self.assertNotEqual(args, ((1, 2, 3),)) self.assertNotEqual(args, ((1, 2, 3), {})) def test_call_with_kwargs(self): args = _Call(((), dict(a=3, b=4))) self.assertEqual(args, (dict(a=3, b=4),)) self.assertEqual(args, ('foo', dict(a=3, b=4))) self.assertEqual(args, ('foo', (), dict(a=3, b=4))) self.assertEqual(args, ((), dict(a=3, b=4))) self.assertEqual(args.args, ()) self.assertEqual(args.kwargs, dict(a=3, b=4)) def test_named_call_with_kwargs(self): args = _Call(('foo', (), dict(a=3, b=4))) self.assertEqual(args, ('foo', dict(a=3, b=4))) self.assertEqual(args, ('foo', (), dict(a=3, b=4))) self.assertEqual(args.args, ()) self.assertEqual(args.kwargs, dict(a=3, b=4)) self.assertNotEqual(args, (dict(a=3, b=4),)) self.assertNotEqual(args, ((), dict(a=3, b=4))) def test_call_with_args_call_empty_name(self): args = _Call(((1, 2, 3), {})) self.assertEqual(args, call(1, 2, 3)) self.assertEqual(call(1, 2, 3), args) self.assertIn(call(1, 2, 3), [args]) def test_call_ne(self): self.assertNotEqual(_Call(((1, 2, 3),)), call(1, 2)) self.assertFalse(_Call(((1, 2, 3),)) != call(1, 2, 3)) self.assertTrue(_Call(((1, 2), {})) != call(1, 2, 3)) def test_call_non_tuples(self): kall = _Call(((1, 2, 3),)) for value in 1, None, self, int: self.assertNotEqual(kall, value) self.assertFalse(kall == value) def test_repr(self): self.assertEqual(repr(_Call()), 'call()') self.assertEqual(repr(_Call(('foo',))), 'call.foo()') self.assertEqual(repr(_Call(((1, 2, 3), {'a': 'b'}))), "call(1, 2, 3, a='b')") self.assertEqual(repr(_Call(('bar', (1, 2, 3), {'a': 'b'}))), "call.bar(1, 2, 3, a='b')") self.assertEqual(repr(call), 'call') self.assertEqual(str(call), 'call') self.assertEqual(repr(call()), 'call()') self.assertEqual(repr(call(1)), 'call(1)') self.assertEqual(repr(call(zz='thing')), "call(zz='thing')") self.assertEqual(repr(call().foo), 'call().foo') self.assertEqual(repr(call(1).foo.bar(a=3).bing), 'call().foo.bar().bing') self.assertEqual( repr(call().foo(1, 2, a=3)), "call().foo(1, 2, a=3)" ) self.assertEqual(repr(call()()), "call()()") self.assertEqual(repr(call(1)(2)), "call()(2)") self.assertEqual( repr(call()().bar().baz.beep(1)), "call()().bar().baz.beep(1)" ) def test_call(self): self.assertEqual(call(), ('', (), {})) self.assertEqual(call('foo', 'bar', one=3, two=4), ('', ('foo', 'bar'), {'one': 3, 'two': 4})) mock = Mock() mock(1, 2, 3) mock(a=3, b=6) self.assertEqual(mock.call_args_list, [call(1, 2, 3), call(a=3, b=6)]) def test_attribute_call(self): self.assertEqual(call.foo(1), ('foo', (1,), {})) self.assertEqual(call.bar.baz(fish='eggs'), ('bar.baz', (), {'fish': 'eggs'})) mock = Mock() mock.foo(1, 2 ,3) mock.bar.baz(a=3, b=6) self.assertEqual(mock.method_calls, [call.foo(1, 2, 3), call.bar.baz(a=3, b=6)]) def test_extended_call(self): result = call(1).foo(2).bar(3, a=4) self.assertEqual(result, ('().foo().bar', (3,), dict(a=4))) mock = MagicMock() mock(1, 2, a=3, b=4) self.assertEqual(mock.call_args, call(1, 2, a=3, b=4)) self.assertNotEqual(mock.call_args, call(1, 2, 3)) self.assertEqual(mock.call_args_list, [call(1, 2, a=3, b=4)]) self.assertEqual(mock.mock_calls, [call(1, 2, a=3, b=4)]) mock = MagicMock() mock.foo(1).bar()().baz.beep(a=6) last_call = call.foo(1).bar()().baz.beep(a=6) self.assertEqual(mock.mock_calls[-1], last_call) self.assertEqual(mock.mock_calls, last_call.call_list()) def test_extended_not_equal(self): a = call(x=1).foo b = call(x=2).foo self.assertEqual(a, a) self.assertEqual(b, b) self.assertNotEqual(a, b) def test_nested_calls_not_equal(self): a = call(x=1).foo().bar b = call(x=2).foo().bar self.assertEqual(a, a) self.assertEqual(b, b) self.assertNotEqual(a, b) def test_call_list(self): mock = MagicMock() mock(1) self.assertEqual(call(1).call_list(), mock.mock_calls) mock = MagicMock() mock(1).method(2) self.assertEqual(call(1).method(2).call_list(), mock.mock_calls) mock = MagicMock() mock(1).method(2)(3) self.assertEqual(call(1).method(2)(3).call_list(), mock.mock_calls) mock = MagicMock() int(mock(1).method(2)(3).foo.bar.baz(4)(5)) kall = call(1).method(2)(3).foo.bar.baz(4)(5).__int__() self.assertEqual(kall.call_list(), mock.mock_calls) def test_call_any(self): self.assertEqual(call, ANY) m = MagicMock() int(m) self.assertEqual(m.mock_calls, [ANY]) self.assertEqual([ANY], m.mock_calls) def test_two_args_call(self): args = _Call(((1, 2), {'a': 3}), two=True) self.assertEqual(len(args), 2) self.assertEqual(args[0], (1, 2)) self.assertEqual(args[1], {'a': 3}) other_args = _Call(((1, 2), {'a': 3})) self.assertEqual(args, other_args) def test_call_with_name(self): self.assertEqual(_Call((), 'foo')[0], 'foo') self.assertEqual(_Call((('bar', 'barz'),),)[0], '') self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '') class SpecSignatureTest(unittest.TestCase): def _check_someclass_mock(self, mock): self.assertRaises(AttributeError, getattr, mock, 'foo') mock.one(1, 2) mock.one.assert_called_with(1, 2) self.assertRaises(AssertionError, mock.one.assert_called_with, 3, 4) self.assertRaises(TypeError, mock.one, 1) mock.two() mock.two.assert_called_with() self.assertRaises(AssertionError, mock.two.assert_called_with, 3) self.assertRaises(TypeError, mock.two, 1) mock.three() mock.three.assert_called_with() self.assertRaises(AssertionError, mock.three.assert_called_with, 3) self.assertRaises(TypeError, mock.three, 3, 2) mock.three(1) mock.three.assert_called_with(1) mock.three(a=1) mock.three.assert_called_with(a=1) def test_basic(self): mock = create_autospec(SomeClass) self._check_someclass_mock(mock) mock = create_autospec(SomeClass()) self._check_someclass_mock(mock) def test_create_autospec_return_value(self): def f(): pass mock = create_autospec(f, return_value='foo') self.assertEqual(mock(), 'foo') class Foo(object): pass mock = create_autospec(Foo, return_value='foo') self.assertEqual(mock(), 'foo') def test_autospec_reset_mock(self): m = create_autospec(int) int(m) m.reset_mock() self.assertEqual(m.__int__.call_count, 0) def test_mocking_unbound_methods(self): class Foo(object): def foo(self, foo): pass p = patch.object(Foo, 'foo') mock_foo = p.start() Foo().foo(1) mock_foo.assert_called_with(1) def test_create_autospec_keyword_arguments(self): class Foo(object): a = 3 m = create_autospec(Foo, a='3') self.assertEqual(m.a, '3') @unittest.skipUnless(six.PY3, "Keyword only arguments Python 3 specific") def test_create_autospec_keyword_only_arguments(self): func_def = "def foo(a, *, b=None): pass\n" namespace = {} exec (func_def, namespace) foo = namespace['foo'] m = create_autospec(foo) m(1) m.assert_called_with(1) self.assertRaises(TypeError, m, 1, 2) m(2, b=3) m.assert_called_with(2, b=3) def test_function_as_instance_attribute(self): obj = SomeClass() def f(a): pass obj.f = f mock = create_autospec(obj) mock.f('bing') mock.f.assert_called_with('bing') def test_spec_as_list(self): # because spec as a list of strings in the mock constructor means # something very different we treat a list instance as the type. mock = create_autospec([]) mock.append('foo') mock.append.assert_called_with('foo') self.assertRaises(AttributeError, getattr, mock, 'foo') class Foo(object): foo = [] mock = create_autospec(Foo) mock.foo.append(3) mock.foo.append.assert_called_with(3) self.assertRaises(AttributeError, getattr, mock.foo, 'foo') def test_attributes(self): class Sub(SomeClass): attr = SomeClass() sub_mock = create_autospec(Sub) for mock in (sub_mock, sub_mock.attr): self._check_someclass_mock(mock) @unittest.skipIf('PyPy' in sys.version, "This fails on pypy, " "see https://github.com/testing-cabal/mock/issues/452") def test_spec_has_descriptor_returning_function(self): class CrazyDescriptor(object): def __get__(self, obj, type_): if obj is None: return lambda x: None class MyClass(object): some_attr = CrazyDescriptor() mock = create_autospec(MyClass) mock.some_attr(1) with self.assertRaises(TypeError): mock.some_attr() with self.assertRaises(TypeError): mock.some_attr(1, 2) @unittest.skipIf(six.PY2, "object.__dir__ doesn't exist in Python 2") def test_spec_has_function_not_in_bases(self): class CrazyClass(object): def __dir__(self): return super(CrazyClass, self).__dir__() + ['crazy'] def __getattr__(self, item): if item == 'crazy': return lambda x: x raise AttributeError(item) inst = CrazyClass() with self.assertRaises(AttributeError): inst.other self.assertEqual(inst.crazy(42), 42) mock = create_autospec(inst) mock.crazy(42) with self.assertRaises(TypeError): mock.crazy() with self.assertRaises(TypeError): mock.crazy(1, 2) @unittest.skipIf('PyPy' in sys.version and sys.version_info < (3, 0), "Fails on pypy2 due to incorrect signature for dict.pop from funcsigs") def test_builtin_functions_types(self): # we could replace builtin functions / methods with a function # with *args / **kwargs signature. Using the builtin method type # as a spec seems to work fairly well though. class BuiltinSubclass(list): def bar(self, arg): pass sorted = sorted attr = {} mock = create_autospec(BuiltinSubclass) mock.append(3) mock.append.assert_called_with(3) self.assertRaises(AttributeError, getattr, mock.append, 'foo') mock.bar('foo') mock.bar.assert_called_with('foo') self.assertRaises(TypeError, mock.bar, 'foo', 'bar') self.assertRaises(AttributeError, getattr, mock.bar, 'foo') mock.sorted([1, 2]) mock.sorted.assert_called_with([1, 2]) self.assertRaises(AttributeError, getattr, mock.sorted, 'foo') mock.attr.pop(3) mock.attr.pop.assert_called_with(3) self.assertRaises(AttributeError, getattr, mock.attr, 'foo') def test_method_calls(self): class Sub(SomeClass): attr = SomeClass() mock = create_autospec(Sub) mock.one(1, 2) mock.two() mock.three(3) expected = [call.one(1, 2), call.two(), call.three(3)] self.assertEqual(mock.method_calls, expected) mock.attr.one(1, 2) mock.attr.two() mock.attr.three(3) expected.extend( [call.attr.one(1, 2), call.attr.two(), call.attr.three(3)] ) self.assertEqual(mock.method_calls, expected) def test_magic_methods(self): class BuiltinSubclass(list): attr = {} mock = create_autospec(BuiltinSubclass) self.assertEqual(list(mock), []) self.assertRaises(TypeError, int, mock) self.assertRaises(TypeError, int, mock.attr) self.assertEqual(list(mock), []) self.assertIsInstance(mock['foo'], MagicMock) self.assertIsInstance(mock.attr['foo'], MagicMock) def test_spec_set(self): class Sub(SomeClass): attr = SomeClass() for spec in (Sub, Sub()): mock = create_autospec(spec, spec_set=True) self._check_someclass_mock(mock) self.assertRaises(AttributeError, setattr, mock, 'foo', 'bar') self.assertRaises(AttributeError, setattr, mock.attr, 'foo', 'bar') def test_descriptors(self): class Foo(object): @classmethod def f(cls, a, b): pass @staticmethod def g(a, b): pass class Bar(Foo): pass class Baz(SomeClass, Bar): pass for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()): mock = create_autospec(spec) mock.f(1, 2) mock.f.assert_called_once_with(1, 2) mock.g(3, 4) mock.g.assert_called_once_with(3, 4) @unittest.skipIf(six.PY3, "No old style classes in Python 3") def test_old_style_classes(self): class Foo: def f(self, a, b): pass class Bar(Foo): g = Foo() for spec in (Foo, Foo(), Bar, Bar()): mock = create_autospec(spec) mock.f(1, 2) mock.f.assert_called_once_with(1, 2) self.assertRaises(AttributeError, getattr, mock, 'foo') self.assertRaises(AttributeError, getattr, mock.f, 'foo') mock.g.f(1, 2) mock.g.f.assert_called_once_with(1, 2) self.assertRaises(AttributeError, getattr, mock.g, 'foo') def test_recursive(self): class A(object): def a(self): pass foo = 'foo bar baz' bar = foo A.B = A mock = create_autospec(A) mock() self.assertFalse(mock.B.called) mock.a() mock.B.a() self.assertEqual(mock.method_calls, [call.a(), call.B.a()]) self.assertIs(A.foo, A.bar) self.assertIsNot(mock.foo, mock.bar) mock.foo.lower() self.assertRaises(AssertionError, mock.bar.lower.assert_called_with) def test_spec_inheritance_for_classes(self): class Foo(object): def a(self, x): pass class Bar(object): def f(self, y): pass class_mock = create_autospec(Foo) self.assertIsNot(class_mock, class_mock()) for this_mock in class_mock, class_mock(): this_mock.a(x=5) this_mock.a.assert_called_with(x=5) this_mock.a.assert_called_with(5) self.assertRaises(TypeError, this_mock.a, 'foo', 'bar') self.assertRaises(AttributeError, getattr, this_mock, 'b') instance_mock = create_autospec(Foo()) instance_mock.a(5) instance_mock.a.assert_called_with(5) instance_mock.a.assert_called_with(x=5) self.assertRaises(TypeError, instance_mock.a, 'foo', 'bar') self.assertRaises(AttributeError, getattr, instance_mock, 'b') # The return value isn't isn't callable self.assertRaises(TypeError, instance_mock) instance_mock.Bar.f(6) instance_mock.Bar.f.assert_called_with(6) instance_mock.Bar.f.assert_called_with(y=6) self.assertRaises(AttributeError, getattr, instance_mock.Bar, 'g') instance_mock.Bar().f(6) instance_mock.Bar().f.assert_called_with(6) instance_mock.Bar().f.assert_called_with(y=6) self.assertRaises(AttributeError, getattr, instance_mock.Bar(), 'g') def test_inherit(self): class Foo(object): a = 3 Foo.Foo = Foo # class mock = create_autospec(Foo) instance = mock() self.assertRaises(AttributeError, getattr, instance, 'b') attr_instance = mock.Foo() self.assertRaises(AttributeError, getattr, attr_instance, 'b') # instance mock = create_autospec(Foo()) self.assertRaises(AttributeError, getattr, mock, 'b') self.assertRaises(TypeError, mock) # attribute instance call_result = mock.Foo() self.assertRaises(AttributeError, getattr, call_result, 'b') def test_builtins(self): # used to fail with infinite recursion create_autospec(1) create_autospec(int) create_autospec('foo') create_autospec(str) create_autospec({}) create_autospec(dict) create_autospec([]) create_autospec(list) create_autospec(set()) create_autospec(set) create_autospec(1.0) create_autospec(float) create_autospec(1j) create_autospec(complex) create_autospec(False) create_autospec(True) def test_function(self): def f(a, b): pass mock = create_autospec(f) self.assertRaises(TypeError, mock) mock(1, 2) mock.assert_called_with(1, 2) mock.assert_called_with(1, b=2) mock.assert_called_with(a=1, b=2) f.f = f mock = create_autospec(f) self.assertRaises(TypeError, mock.f) mock.f(3, 4) mock.f.assert_called_with(3, 4) mock.f.assert_called_with(a=3, b=4) def test_skip_attributeerrors(self): class Raiser(object): def __get__(self, obj, type=None): if obj is None: raise AttributeError('Can only be accessed via an instance') class RaiserClass(object): raiser = Raiser() @staticmethod def existing(a, b): return a + b self.assertEqual(RaiserClass.existing(1, 2), 3) s = create_autospec(RaiserClass) self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3)) self.assertEqual(s.existing(1, 2), s.existing.return_value) self.assertRaises(AttributeError, lambda: s.nonexisting) # check we can fetch the raiser attribute and it has no spec obj = s.raiser obj.foo, obj.bar def test_signature_class(self): class Foo(object): def __init__(self, a, b=3): pass mock = create_autospec(Foo) self.assertRaises(TypeError, mock) mock(1) mock.assert_called_once_with(1) mock(4, 5) mock.assert_called_with(4, 5) @unittest.skipIf(six.PY3, 'no old style classes in Python 3') def test_signature_old_style_class(self): class Foo: def __init__(self, a, b=3): pass mock = create_autospec(Foo) self.assertRaises(TypeError, mock) mock(1) mock.assert_called_once_with(1) mock.assert_called_once_with(a=1) self.assertRaises(AssertionError, mock.assert_called_once_with, 2) mock(4, 5) mock.assert_called_with(4, 5) mock.assert_called_with(a=4, b=5) self.assertRaises(AssertionError, mock.assert_called_with, a=5, b=4) def test_class_with_no_init(self): # this used to raise an exception # due to trying to get a signature from object.__init__ class Foo(object): pass create_autospec(Foo) @unittest.skipIf(six.PY3, 'no old style classes in Python 3') def test_old_style_class_with_no_init(self): # this used to raise an exception # due to Foo.__init__ raising an AttributeError class Foo: pass create_autospec(Foo) def test_signature_callable(self): class Callable(object): def __init__(self, x, y): pass def __call__(self, a): pass mock = create_autospec(Callable) mock(1, 2) mock.assert_called_once_with(1, 2) mock.assert_called_once_with(x=1, y=2) self.assertRaises(TypeError, mock, 'a') instance = mock(1, 2) self.assertRaises(TypeError, instance) instance(a='a') instance.assert_called_once_with('a') instance.assert_called_once_with(a='a') instance('a') instance.assert_called_with('a') instance.assert_called_with(a='a') mock = create_autospec(Callable(1, 2)) mock(a='a') mock.assert_called_once_with(a='a') self.assertRaises(TypeError, mock) mock('a') mock.assert_called_with('a') def test_signature_noncallable(self): class NonCallable(object): def __init__(self): pass mock = create_autospec(NonCallable) instance = mock() mock.assert_called_once_with() self.assertRaises(TypeError, mock, 'a') self.assertRaises(TypeError, instance) self.assertRaises(TypeError, instance, 'a') mock = create_autospec(NonCallable()) self.assertRaises(TypeError, mock) self.assertRaises(TypeError, mock, 'a') def test_create_autospec_none(self): class Foo(object): bar = None mock = create_autospec(Foo) none = mock.bar self.assertNotIsInstance(none, type(None)) none.foo() none.foo.assert_called_once_with() def test_autospec_functions_with_self_in_odd_place(self): class Foo(object): def f(a, self): pass a = create_autospec(Foo) a.f(10) a.f.assert_called_with(10) a.f.assert_called_with(self=10) a.f(self=10) a.f.assert_called_with(10) a.f.assert_called_with(self=10) def test_autospec_property(self): class Foo(object): @property def foo(self): pass foo = create_autospec(Foo) mock_property = foo.foo # no spec on properties self.assertIsInstance(mock_property, MagicMock) mock_property(1, 2, 3) mock_property.abc(4, 5, 6) mock_property.assert_called_once_with(1, 2, 3) mock_property.abc.assert_called_once_with(4, 5, 6) def test_autospec_slots(self): class Foo(object): __slots__ = ['a'] foo = create_autospec(Foo) mock_slot = foo.a # no spec on slots mock_slot(1, 2, 3) mock_slot.abc(4, 5, 6) mock_slot.assert_called_once_with(1, 2, 3) mock_slot.abc.assert_called_once_with(4, 5, 6) def test_autospec_data_descriptor(self): class Descriptor(object): def __init__(self, value): self.value = value def __get__(self, obj, cls=None): return self def __set__(self, obj, value): pass class MyProperty(property): pass class Foo(object): __slots__ = ['slot'] @property def prop(self): pass @MyProperty def subprop(self): pass desc = Descriptor(42) foo = create_autospec(Foo) def check_data_descriptor(mock_attr): # Data descriptors don't have a spec. self.assertIsInstance(mock_attr, MagicMock) mock_attr(1, 2, 3) mock_attr.abc(4, 5, 6) mock_attr.assert_called_once_with(1, 2, 3) mock_attr.abc.assert_called_once_with(4, 5, 6) # property check_data_descriptor(foo.prop) # property subclass check_data_descriptor(foo.subprop) # class __slot__ check_data_descriptor(foo.slot) # plain data descriptor check_data_descriptor(foo.desc) @unittest.skipIf('PyPy' in sys.version and sys.version_info > (3, 0), "See https://github.com/testing-cabal/mock/issues/452") def test_autospec_on_bound_builtin_function(self): meth = six.create_bound_method(time.ctime, time.time()) self.assertIsInstance(meth(), str) mocked = create_autospec(meth) # no signature, so no spec to check against mocked() mocked.assert_called_once_with() mocked.reset_mock() mocked(4, 5, 6) mocked.assert_called_once_with(4, 5, 6) def test_autospec_socket(self): sock_class = create_autospec(socket.socket) self.assertRaises(TypeError, sock_class, foo=1) def test_autospec_getattr_partial_function(self): # bpo-32153 : getattr returning partial functions without # __name__ should not create AttributeError in create_autospec class Foo(object): def __getattr__(self, attribute): return partial(lambda name: name, attribute) proxy = Foo() autospec = create_autospec(proxy) self.assertFalse(hasattr(autospec, '__name__')) def test_spec_inspect_signature(self): def myfunc(x, y): pass mock = create_autospec(myfunc) mock(1, 2) mock(x=1, y=2) if six.PY2: self.assertEqual(funcsigs.signature(mock), funcsigs.signature(myfunc)) else: self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc)) self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)]) self.assertRaises(TypeError, mock, 1) def test_spec_function_no_name(self): func = lambda: 'nope' mock = create_autospec(func) self.assertEqual(mock.__name__, 'funcopy') @unittest.skipIf(six.PY3, "Here to test our Py2 _isidentifier") def test_spec_function_has_identifier_name(self): func = lambda: 'nope' func.__name__ = 'global' mock = create_autospec(func) self.assertEqual(mock.__name__, 'funcopy') def test_spec_function_assert_has_calls(self): def f(a): pass mock = create_autospec(f) mock(1) mock.assert_has_calls([call(1)]) with self.assertRaises(AssertionError): mock.assert_has_calls([call(2)]) def test_spec_function_assert_any_call(self): def f(a): pass mock = create_autospec(f) mock(1) mock.assert_any_call(1) with self.assertRaises(AssertionError): mock.assert_any_call(2) def test_spec_function_reset_mock(self): def f(a): pass rv = Mock() mock = create_autospec(f, return_value=rv) mock(1)(2) self.assertEqual(mock.mock_calls, [call(1)]) self.assertEqual(rv.mock_calls, [call(2)]) mock.reset_mock() self.assertEqual(mock.mock_calls, []) self.assertEqual(rv.mock_calls, []) class TestCallList(unittest.TestCase): def test_args_list_contains_call_list(self): mock = Mock() self.assertIsInstance(mock.call_args_list, _CallList) mock(1, 2) mock(a=3) mock(3, 4) mock(b=6) for kall in call(1, 2), call(a=3), call(3, 4), call(b=6): self.assertIn(kall, mock.call_args_list) calls = [call(a=3), call(3, 4)] self.assertIn(calls, mock.call_args_list) calls = [call(1, 2), call(a=3)] self.assertIn(calls, mock.call_args_list) calls = [call(3, 4), call(b=6)] self.assertIn(calls, mock.call_args_list) calls = [call(3, 4)] self.assertIn(calls, mock.call_args_list) self.assertNotIn(call('fish'), mock.call_args_list) self.assertNotIn([call('fish')], mock.call_args_list) def test_call_list_str(self): mock = Mock() mock(1, 2) mock.foo(a=3) mock.foo.bar().baz('fish', cat='dog') expected = ( "[call(1, 2),\n" " call.foo(a=3),\n" " call.foo.bar(),\n" " call.foo.bar().baz('fish', cat='dog')]" ) self.assertEqual(str(mock.mock_calls), expected) @unittest.skipIf(six.PY3, "Unicode is properly handled with Python 3") def test_call_list_unicode(self): # See github issue #328 mock = Mock() class NonAsciiRepr(object): def __repr__(self): return "\xe9" mock(**{unicode("a"): NonAsciiRepr()}) self.assertEqual(str(mock.mock_calls), "[call(a=\xe9)]") def test_propertymock(self): p = patch('%s.SomeClass.one' % __name__, new_callable=PropertyMock) mock = p.start() try: SomeClass.one mock.assert_called_once_with() s = SomeClass() s.one mock.assert_called_with() self.assertEqual(mock.mock_calls, [call(), call()]) s.one = 3 self.assertEqual(mock.mock_calls, [call(), call(), call(3)]) finally: p.stop() def test_propertymock_returnvalue(self): m = MagicMock() p = PropertyMock() type(m).foo = p returned = m.foo p.assert_called_once_with() self.assertIsInstance(returned, MagicMock) self.assertNotIsInstance(returned, PropertyMock) class TestCallablePredicate(unittest.TestCase): def test_type(self): for obj in [str, bytes, int, list, tuple, SomeClass]: self.assertTrue(_callable(obj)) def test_call_magic_method(self): class Callable: def __call__(self): pass instance = Callable() self.assertTrue(_callable(instance)) def test_staticmethod(self): class WithStaticMethod: @staticmethod def staticfunc(): pass self.assertTrue(_callable(WithStaticMethod.staticfunc)) def test_non_callable_staticmethod(self): class BadStaticMethod: not_callable = staticmethod(None) self.assertFalse(_callable(BadStaticMethod.not_callable)) def test_classmethod(self): class WithClassMethod: @classmethod def classfunc(cls): pass self.assertTrue(_callable(WithClassMethod.classfunc)) def test_non_callable_classmethod(self): class BadClassMethod: not_callable = classmethod(None) self.assertFalse(_callable(BadClassMethod.not_callable)) if __name__ == '__main__': unittest.main() mock-3.0.5/mock/tests/testhelpers_py3.py000066400000000000000000000011751346437275100202720ustar00rootroot00000000000000import inspect import unittest from mock import call, create_autospec class CallTest(unittest.TestCase): def test_spec_inspect_signature_annotations(self): def foo(a: int, b: int=10, *, c:int) -> int: return a + b + c self.assertEqual(foo(1, 2, c=3), 6) mock = create_autospec(foo) mock(1, 2, c=3) mock(1, c=3) self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(foo)) self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)]) self.assertRaises(TypeError, mock, 1) self.assertRaises(TypeError, mock, 1, 2, 3, c=4) mock-3.0.5/mock/tests/testmagicmethods.py000066400000000000000000000414731346437275100205060ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ from __future__ import division try: unicode except NameError: # Python 3 unicode = str long = int import math import os import sys import textwrap import unittest import six from mock import Mock, MagicMock from mock.mock import _magics class TestMockingMagicMethods(unittest.TestCase): def test_deleting_magic_methods(self): mock = Mock() self.assertFalse(hasattr(mock, '__getitem__')) mock.__getitem__ = Mock() self.assertTrue(hasattr(mock, '__getitem__')) del mock.__getitem__ self.assertFalse(hasattr(mock, '__getitem__')) def test_magicmock_del(self): mock = MagicMock() # before using getitem del mock.__getitem__ self.assertRaises(TypeError, lambda: mock['foo']) mock = MagicMock() # this time use it first mock['foo'] del mock.__getitem__ self.assertRaises(TypeError, lambda: mock['foo']) def test_magic_method_wrapping(self): mock = Mock() def f(self, name): return self, 'fish' mock.__getitem__ = f self.assertIsNot(mock.__getitem__, f) self.assertEqual(mock['foo'], (mock, 'fish')) self.assertEqual(mock.__getitem__('foo'), (mock, 'fish')) mock.__getitem__ = mock self.assertIs(mock.__getitem__, mock) def test_magic_methods_isolated_between_mocks(self): mock1 = Mock() mock2 = Mock() mock1.__iter__ = Mock(return_value=iter([])) self.assertEqual(list(mock1), []) self.assertRaises(TypeError, lambda: list(mock2)) def test_repr(self): mock = Mock() self.assertEqual(repr(mock), "" % id(mock)) mock.__repr__ = lambda s: 'foo' self.assertEqual(repr(mock), 'foo') def test_str(self): mock = Mock() self.assertEqual(str(mock), object.__str__(mock)) mock.__str__ = lambda s: 'foo' self.assertEqual(str(mock), 'foo') @unittest.skipIf(six.PY3, "no unicode in Python 3") def test_unicode(self): mock = Mock() self.assertEqual(unicode(mock), unicode(str(mock))) mock.__unicode__ = lambda s: unicode('foo') self.assertEqual(unicode(mock), unicode('foo')) def test_dict_methods(self): mock = Mock() self.assertRaises(TypeError, lambda: mock['foo']) def _del(): del mock['foo'] def _set(): mock['foo'] = 3 self.assertRaises(TypeError, _del) self.assertRaises(TypeError, _set) _dict = {} def getitem(s, name): return _dict[name] def setitem(s, name, value): _dict[name] = value def delitem(s, name): del _dict[name] mock.__setitem__ = setitem mock.__getitem__ = getitem mock.__delitem__ = delitem self.assertRaises(KeyError, lambda: mock['foo']) mock['foo'] = 'bar' self.assertEqual(_dict, {'foo': 'bar'}) self.assertEqual(mock['foo'], 'bar') del mock['foo'] self.assertEqual(_dict, {}) def test_numeric(self): original = mock = Mock() mock.value = 0 self.assertRaises(TypeError, lambda: mock + 3) def add(self, other): mock.value += other return self mock.__add__ = add self.assertEqual(mock + 3, mock) self.assertEqual(mock.value, 3) del mock.__add__ def iadd(mock): mock += 3 self.assertRaises(TypeError, iadd, mock) mock.__iadd__ = add mock += 6 self.assertEqual(mock, original) self.assertEqual(mock.value, 9) self.assertRaises(TypeError, lambda: 3 + mock) mock.__radd__ = add self.assertEqual(7 + mock, mock) self.assertEqual(mock.value, 16) def test_division(self): original = mock = Mock() mock.value = 32 self.assertRaises(TypeError, lambda: mock / 2) def truediv(self, other): mock.value /= other return self mock.__truediv__ = truediv self.assertEqual(mock / 2, mock) self.assertEqual(mock.value, 16) del mock.__truediv__ if six.PY3: def itruediv(mock): mock /= 4 self.assertRaises(TypeError, itruediv, mock) mock.__itruediv__ = truediv mock /= 8 self.assertEqual(mock, original) self.assertEqual(mock.value, 2) else: mock.value = 2 self.assertRaises(TypeError, lambda: 8 / mock) mock.__rtruediv__ = truediv self.assertEqual(0.5 / mock, mock) self.assertEqual(mock.value, 4) def test_hash(self): mock = Mock() # test delegation self.assertEqual(hash(mock), Mock.__hash__(mock)) def _hash(s): return 3 mock.__hash__ = _hash self.assertEqual(hash(mock), 3) def test_nonzero(self): m = Mock() self.assertTrue(bool(m)) nonzero = lambda s: False if six.PY2: m.__nonzero__ = nonzero else: m.__bool__ = nonzero self.assertFalse(bool(m)) def test_comparison(self): mock = Mock() def comp(s, o): return True mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp self. assertTrue(mock < 3) self. assertTrue(mock > 3) self. assertTrue(mock <= 3) self. assertTrue(mock >= 3) if six.PY2: # incomparable in Python 3 self.assertEqual(Mock() < 3, object() < 3) self.assertEqual(Mock() > 3, object() > 3) self.assertEqual(Mock() <= 3, object() <= 3) self.assertEqual(Mock() >= 3, object() >= 3) else: self.assertRaises(TypeError, lambda: MagicMock() < object()) self.assertRaises(TypeError, lambda: object() < MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() < MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() > object()) self.assertRaises(TypeError, lambda: object() > MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() > MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() <= object()) self.assertRaises(TypeError, lambda: object() <= MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() <= MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() >= object()) self.assertRaises(TypeError, lambda: object() >= MagicMock()) self.assertRaises(TypeError, lambda: MagicMock() >= MagicMock()) def test_equality(self): for mock in Mock(), MagicMock(): self.assertEqual(mock == mock, True) self.assertIsInstance(mock == mock, bool) self.assertEqual(mock != mock, False) self.assertIsInstance(mock != mock, bool) self.assertEqual(mock == object(), False) self.assertEqual(mock != object(), True) def eq(self, other): return other == 3 mock.__eq__ = eq self.assertTrue(mock == 3) self.assertFalse(mock == 4) def ne(self, other): return other == 3 mock.__ne__ = ne self.assertTrue(mock != 3) self.assertFalse(mock != 4) mock = MagicMock() mock.__eq__.return_value = True self.assertIsInstance(mock == 3, bool) self.assertEqual(mock == 3, True) mock.__ne__.return_value = False self.assertIsInstance(mock != 3, bool) self.assertEqual(mock != 3, False) def test_len_contains_iter(self): mock = Mock() self.assertRaises(TypeError, len, mock) self.assertRaises(TypeError, iter, mock) self.assertRaises(TypeError, lambda: 'foo' in mock) mock.__len__ = lambda s: 6 self.assertEqual(len(mock), 6) mock.__contains__ = lambda s, o: o == 3 self.assertIn(3, mock) self.assertNotIn(6, mock) mock.__iter__ = lambda s: iter('foobarbaz') self.assertEqual(list(mock), list('foobarbaz')) def test_magicmock(self): mock = MagicMock() mock.__iter__.return_value = iter([1, 2, 3]) self.assertEqual(list(mock), [1, 2, 3]) name = '__nonzero__' other = '__bool__' if six.PY3: name, other = other, name getattr(mock, name).return_value = False self.assertFalse(hasattr(mock, other)) self.assertFalse(bool(mock)) for entry in _magics: self.assertTrue(hasattr(mock, entry)) self.assertFalse(hasattr(mock, '__imaginary__')) def test_magic_mock_equality(self): mock = MagicMock() self.assertIsInstance(mock == object(), bool) self.assertIsInstance(mock != object(), bool) self.assertEqual(mock == object(), False) self.assertEqual(mock != object(), True) self.assertEqual(mock == mock, True) self.assertEqual(mock != mock, False) def test_magicmock_defaults(self): mock = MagicMock() self.assertEqual(int(mock), 1) self.assertEqual(complex(mock), 1j) self.assertEqual(float(mock), 1.0) self.assertEqual(long(mock), long(1)) self.assertNotIn(object(), mock) self.assertEqual(len(mock), 0) self.assertEqual(list(mock), []) self.assertEqual(hash(mock), object.__hash__(mock)) self.assertEqual(str(mock), object.__str__(mock)) self.assertEqual(unicode(mock), object.__str__(mock)) self.assertIsInstance(unicode(mock), unicode) self.assertTrue(bool(mock)) self.assertEqual(math.trunc(mock), mock.__trunc__()) if six.PY2: # These fall back to __float__ in Python 2: self.assertEqual(round(mock), 1.0) self.assertEqual(math.floor(mock), 1.0) self.assertEqual(math.ceil(mock), 1.0) else: self.assertEqual(round(mock), mock.__round__()) self.assertEqual(math.floor(mock), mock.__floor__()) self.assertEqual(math.ceil(mock), mock.__ceil__()) if six.PY2: self.assertEqual(oct(mock), '1') else: # in Python 3 oct and hex use __index__ # so these tests are for __index__ in py3k self.assertEqual(oct(mock), '0o1') self.assertEqual(hex(mock), '0x1') # how to test __sizeof__ ? @unittest.skipIf(six.PY3, "no __cmp__ in Python 3") def test_non_default_magic_methods(self): mock = MagicMock() self.assertRaises(AttributeError, lambda: mock.__cmp__) mock = Mock() mock.__cmp__ = lambda s, o: 0 self.assertEqual(mock, object()) def test_magic_methods_fspath(self): mock = MagicMock() if sys.version_info < (3, 6): self.assertRaises(AttributeError, lambda: mock.__fspath__) else: expected_path = mock.__fspath__() mock.reset_mock() self.assertEqual(os.fspath(mock), expected_path) mock.__fspath__.assert_called_once() def test_magic_methods_and_spec(self): class Iterable(object): def __iter__(self): pass mock = Mock(spec=Iterable) self.assertRaises(AttributeError, lambda: mock.__iter__) mock.__iter__ = Mock(return_value=iter([])) self.assertEqual(list(mock), []) class NonIterable(object): pass mock = Mock(spec=NonIterable) self.assertRaises(AttributeError, lambda: mock.__iter__) def set_int(): mock.__int__ = Mock(return_value=iter([])) self.assertRaises(AttributeError, set_int) mock = MagicMock(spec=Iterable) self.assertEqual(list(mock), []) self.assertRaises(AttributeError, set_int) def test_magic_methods_and_spec_set(self): class Iterable(object): def __iter__(self): pass mock = Mock(spec_set=Iterable) self.assertRaises(AttributeError, lambda: mock.__iter__) mock.__iter__ = Mock(return_value=iter([])) self.assertEqual(list(mock), []) class NonIterable(object): pass mock = Mock(spec_set=NonIterable) self.assertRaises(AttributeError, lambda: mock.__iter__) def set_int(): mock.__int__ = Mock(return_value=iter([])) self.assertRaises(AttributeError, set_int) mock = MagicMock(spec_set=Iterable) self.assertEqual(list(mock), []) self.assertRaises(AttributeError, set_int) def test_setting_unsupported_magic_method(self): mock = MagicMock() def set_setattr(): mock.__setattr__ = lambda self, name: None self.assertRaisesRegexp(AttributeError, "Attempting to set unsupported magic method '__setattr__'.", set_setattr ) def test_attributes_and_return_value(self): mock = MagicMock() attr = mock.foo def _get_type(obj): # the type of every mock (or magicmock) is a custom subclass # so the real type is the second in the mro return type(obj).__mro__[1] self.assertEqual(_get_type(attr), MagicMock) returned = mock() self.assertEqual(_get_type(returned), MagicMock) def test_magic_methods_are_magic_mocks(self): mock = MagicMock() self.assertIsInstance(mock.__getitem__, MagicMock) mock[1][2].__getitem__.return_value = 3 self.assertEqual(mock[1][2][3], 3) def test_magic_method_reset_mock(self): mock = MagicMock() str(mock) self.assertTrue(mock.__str__.called) mock.reset_mock() self.assertFalse(mock.__str__.called) def test_dir(self): # overriding the default implementation for mock in Mock(), MagicMock(): def _dir(self): return ['foo'] mock.__dir__ = _dir self.assertEqual(dir(mock), ['foo']) @unittest.skipIf('PyPy' in sys.version, "This fails differently on pypy") def test_bound_methods(self): m = Mock() # XXXX should this be an expected failure instead? # this seems like it should work, but is hard to do without introducing # other api inconsistencies. Failure message could be better though. m.__iter__ = [3].__iter__ self.assertRaises(TypeError, iter, m) def test_magic_method_type(self): class Foo(MagicMock): pass foo = Foo() self.assertIsInstance(foo.__int__, Foo) def test_descriptor_from_class(self): m = MagicMock() type(m).__str__.return_value = 'foo' self.assertEqual(str(m), 'foo') def test_iterable_as_iter_return_value(self): m = MagicMock() m.__iter__.return_value = [1, 2, 3] self.assertEqual(list(m), [1, 2, 3]) self.assertEqual(list(m), [1, 2, 3]) m.__iter__.return_value = iter([4, 5, 6]) self.assertEqual(list(m), [4, 5, 6]) self.assertEqual(list(m), []) @unittest.skipIf(sys.version_info < (3, 5), "@ added in Python 3.5") def test_matmul(self): src = textwrap.dedent("""\ m = MagicMock() self.assertIsInstance(m @ 1, MagicMock) m.__matmul__.return_value = 42 m.__rmatmul__.return_value = 666 m.__imatmul__.return_value = 24 self.assertEqual(m @ 1, 42) self.assertEqual(1 @ m, 666) m @= 24 self.assertEqual(m, 24) """) exec(src) def test_divmod_and_rdivmod(self): m = MagicMock() self.assertIsInstance(divmod(5, m), MagicMock) m.__divmod__.return_value = (2, 1) self.assertEqual(divmod(m, 2), (2, 1)) m = MagicMock() foo = divmod(2, m) self.assertIsInstance(foo, MagicMock) foo_direct = m.__divmod__(2) self.assertIsInstance(foo_direct, MagicMock) bar = divmod(m, 2) self.assertIsInstance(bar, MagicMock) bar_direct = m.__rdivmod__(2) self.assertIsInstance(bar_direct, MagicMock) # http://bugs.python.org/issue23310 # Check if you can change behaviour of magic methods in MagicMock init def test_magic_in_initialization(self): m = MagicMock(**{'__str__.return_value': "12"}) self.assertEqual(str(m), "12") def test_changing_magic_set_in_initialization(self): m = MagicMock(**{'__str__.return_value': "12"}) m.__str__.return_value = "13" self.assertEqual(str(m), "13") m = MagicMock(**{'__str__.return_value': "12"}) m.configure_mock(**{'__str__.return_value': "14"}) self.assertEqual(str(m), "14") if __name__ == '__main__': unittest.main() mock-3.0.5/mock/tests/testmock.py000066400000000000000000001750141346437275100167720ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ import copy import pickle import re import sys import tempfile import six import unittest import mock from mock.mock import ( call, DEFAULT, patch, sentinel, MagicMock, Mock, NonCallableMock, NonCallableMagicMock, _Call, _CallList, create_autospec ) from mock.tests.support import is_instance try: unicode except NameError: unicode = str class Iter(object): def __init__(self): self.thing = iter(['this', 'is', 'an', 'iter']) def __iter__(self): return self def next(self): return next(self.thing) __next__ = next class Something(object): def meth(self, a, b, c, d=None): pass @classmethod def cmeth(cls, a, b, c, d=None): pass @staticmethod def smeth(a, b, c, d=None): pass class Subclass(MagicMock): pass class Thing(object): attribute = 6 foo = 'bar' class MockTest(unittest.TestCase): def test_all(self): # if __all__ is badly defined then import * will raise an error # We have to exec it because you can't import * inside a method # in Python 3 exec("from mock import *") def test_constructor(self): mock = Mock() self.assertFalse(mock.called, "called not initialised correctly") self.assertEqual(mock.call_count, 0, "call_count not initialised correctly") self.assertTrue(is_instance(mock.return_value, Mock), "return_value not initialised correctly") self.assertEqual(mock.call_args, None, "call_args not initialised correctly") self.assertEqual(mock.call_args_list, [], "call_args_list not initialised correctly") self.assertEqual(mock.method_calls, [], "method_calls not initialised correctly") # Can't use hasattr for this test as it always returns True on a mock self.assertNotIn('_items', mock.__dict__, "default mock should not have '_items' attribute") self.assertIsNone(mock._mock_parent, "parent not initialised correctly") self.assertIsNone(mock._mock_methods, "methods not initialised correctly") self.assertEqual(mock._mock_children, {}, "children not initialised incorrectly") def test_return_value_in_constructor(self): mock = Mock(return_value=None) self.assertIsNone(mock.return_value, "return value in constructor not honoured") def test_change_return_value_via_delegate(self): def f(): pass mock = create_autospec(f) mock.mock.return_value = 1 self.assertEqual(mock(), 1) def test_change_side_effect_via_delegate(self): def f(): pass mock = create_autospec(f) mock.mock.side_effect = TypeError() with self.assertRaises(TypeError): mock() def test_repr(self): mock = Mock(name='foo') self.assertIn('foo', repr(mock)) self.assertIn("'%s'" % id(mock), repr(mock)) mocks = [(Mock(), 'mock'), (Mock(name='bar'), 'bar')] for mock, name in mocks: self.assertIn('%s.bar' % name, repr(mock.bar)) self.assertIn('%s.foo()' % name, repr(mock.foo())) self.assertIn('%s.foo().bing' % name, repr(mock.foo().bing)) self.assertIn('%s()' % name, repr(mock())) self.assertIn('%s()()' % name, repr(mock()())) self.assertIn('%s()().foo.bar.baz().bing' % name, repr(mock()().foo.bar.baz().bing)) def test_repr_with_spec(self): class X(object): pass mock = Mock(spec=X) self.assertIn(" spec='X' ", repr(mock)) mock = Mock(spec=X()) self.assertIn(" spec='X' ", repr(mock)) mock = Mock(spec_set=X) self.assertIn(" spec_set='X' ", repr(mock)) mock = Mock(spec_set=X()) self.assertIn(" spec_set='X' ", repr(mock)) mock = Mock(spec=X, name='foo') self.assertIn(" spec='X' ", repr(mock)) self.assertIn(" name='foo' ", repr(mock)) mock = Mock(name='foo') self.assertNotIn("spec", repr(mock)) mock = Mock() self.assertNotIn("spec", repr(mock)) mock = Mock(spec=['foo']) self.assertNotIn("spec", repr(mock)) def test_side_effect(self): mock = Mock() def effect(*args, **kwargs): raise SystemError('kablooie') mock.side_effect = effect self.assertRaises(SystemError, mock, 1, 2, fish=3) mock.assert_called_with(1, 2, fish=3) results = [1, 2, 3] def effect(): return results.pop() mock.side_effect = effect self.assertEqual([mock(), mock(), mock()], [3, 2, 1], "side effect not used correctly") mock = Mock(side_effect=sentinel.SideEffect) self.assertEqual(mock.side_effect, sentinel.SideEffect, "side effect in constructor not used") def side_effect(): return DEFAULT mock = Mock(side_effect=side_effect, return_value=sentinel.RETURN) self.assertEqual(mock(), sentinel.RETURN) def test_autospec_side_effect(self): # Test for issue17826 results = [1, 2, 3] def effect(): return results.pop() def f(): pass mock = create_autospec(f) mock.side_effect = [1, 2, 3] self.assertEqual([mock(), mock(), mock()], [1, 2, 3], "side effect not used correctly in create_autospec") # Test where side effect is a callable results = [1, 2, 3] mock = create_autospec(f) mock.side_effect = effect self.assertEqual([mock(), mock(), mock()], [3, 2, 1], "callable side effect not used correctly") def test_autospec_side_effect_exception(self): # Test for issue 23661 def f(): pass mock = create_autospec(f) mock.side_effect = ValueError('Bazinga!') self.assertRaisesRegexp(ValueError, 'Bazinga!', mock) def test_reset_mock(self): parent = Mock() spec = ["something"] mock = Mock(name="child", parent=parent, spec=spec) mock(sentinel.Something, something=sentinel.SomethingElse) something = mock.something mock.something() mock.side_effect = sentinel.SideEffect return_value = mock.return_value return_value() mock.reset_mock() self.assertEqual(mock._mock_name, "child", "name incorrectly reset") self.assertEqual(mock._mock_parent, parent, "parent incorrectly reset") self.assertEqual(mock._mock_methods, spec, "methods incorrectly reset") self.assertFalse(mock.called, "called not reset") self.assertEqual(mock.call_count, 0, "call_count not reset") self.assertEqual(mock.call_args, None, "call_args not reset") self.assertEqual(mock.call_args_list, [], "call_args_list not reset") self.assertEqual(mock.method_calls, [], "method_calls not initialised correctly: %r != %r" % (mock.method_calls, [])) self.assertEqual(mock.mock_calls, []) self.assertEqual(mock.side_effect, sentinel.SideEffect, "side_effect incorrectly reset") self.assertEqual(mock.return_value, return_value, "return_value incorrectly reset") self.assertFalse(return_value.called, "return value mock not reset") self.assertEqual(mock._mock_children, {'something': something}, "children reset incorrectly") self.assertEqual(mock.something, something, "children incorrectly cleared") self.assertFalse(mock.something.called, "child not reset") def test_reset_mock_recursion(self): mock = Mock() mock.return_value = mock # used to cause recursion mock.reset_mock() def test_reset_mock_on_mock_open_issue_18622(self): a = mock.mock_open() a.reset_mock() def test_call(self): mock = Mock() self.assertTrue(is_instance(mock.return_value, Mock), "Default return_value should be a Mock") result = mock() self.assertEqual(mock(), result, "different result from consecutive calls") mock.reset_mock() ret_val = mock(sentinel.Arg) self.assertTrue(mock.called, "called not set") self.assertEqual(mock.call_count, 1, "call_count incoreect") self.assertEqual(mock.call_args, ((sentinel.Arg,), {}), "call_args not set") self.assertEqual(mock.call_args.args, (sentinel.Arg,), "call_args not set") self.assertEqual(mock.call_args.kwargs, {}, "call_args not set") self.assertEqual(mock.call_args_list, [((sentinel.Arg,), {})], "call_args_list not initialised correctly") mock.return_value = sentinel.ReturnValue ret_val = mock(sentinel.Arg, key=sentinel.KeyArg) self.assertEqual(ret_val, sentinel.ReturnValue, "incorrect return value") self.assertEqual(mock.call_count, 2, "call_count incorrect") self.assertEqual(mock.call_args, ((sentinel.Arg,), {'key': sentinel.KeyArg}), "call_args not set") self.assertEqual(mock.call_args_list, [ ((sentinel.Arg,), {}), ((sentinel.Arg,), {'key': sentinel.KeyArg}) ], "call_args_list not set") def test_call_args_comparison(self): mock = Mock() mock() mock(sentinel.Arg) mock(kw=sentinel.Kwarg) mock(sentinel.Arg, kw=sentinel.Kwarg) self.assertEqual(mock.call_args_list, [ (), ((sentinel.Arg,),), ({"kw": sentinel.Kwarg},), ((sentinel.Arg,), {"kw": sentinel.Kwarg}) ]) self.assertEqual(mock.call_args, ((sentinel.Arg,), {"kw": sentinel.Kwarg})) self.assertEqual(mock.call_args.args, (sentinel.Arg,)) self.assertEqual(mock.call_args.kwargs, {"kw": sentinel.Kwarg}) # Comparing call_args to a long sequence should not raise # an exception. See issue 24857. self.assertFalse(mock.call_args == "a long sequence") def test_calls_equal_with_any(self): # Check that equality and non-equality is consistent even when # comparing with mock.ANY mm = mock.MagicMock() self.assertTrue(mm == mm) self.assertFalse(mm != mm) self.assertFalse(mm == mock.MagicMock()) self.assertTrue(mm != mock.MagicMock()) self.assertTrue(mm == mock.ANY) self.assertFalse(mm != mock.ANY) self.assertTrue(mock.ANY == mm) self.assertFalse(mock.ANY != mm) call1 = mock.call(mock.MagicMock()) call2 = mock.call(mock.ANY) self.assertTrue(call1 == call2) self.assertFalse(call1 != call2) self.assertTrue(call2 == call1) self.assertFalse(call2 != call1) def test_assert_called_with(self): mock = Mock() mock() # Will raise an exception if it fails mock.assert_called_with() self.assertRaises(AssertionError, mock.assert_called_with, 1) mock.reset_mock() self.assertRaises(AssertionError, mock.assert_called_with) mock(1, 2, 3, a='fish', b='nothing') mock.assert_called_with(1, 2, 3, a='fish', b='nothing') def test_assert_called_with_any(self): m = MagicMock() m(MagicMock()) m.assert_called_with(mock.ANY) def test_assert_called_with_function_spec(self): def f(a, b, c, d=None): pass mock = Mock(spec=f) mock(1, b=2, c=3) mock.assert_called_with(1, 2, 3) mock.assert_called_with(a=1, b=2, c=3) self.assertRaises(AssertionError, mock.assert_called_with, 1, b=3, c=2) # Expected call doesn't match the spec's signature with self.assertRaises(AssertionError) as cm: mock.assert_called_with(e=8) if hasattr(cm.exception, '__cause__'): self.assertIsInstance(cm.exception.__cause__, TypeError) def test_assert_called_with_method_spec(self): def _check(mock): mock(1, b=2, c=3) mock.assert_called_with(1, 2, 3) mock.assert_called_with(a=1, b=2, c=3) self.assertRaises(AssertionError, mock.assert_called_with, 1, b=3, c=2) mock = Mock(spec=Something().meth) _check(mock) mock = Mock(spec=Something.cmeth) _check(mock) mock = Mock(spec=Something().cmeth) _check(mock) mock = Mock(spec=Something.smeth) _check(mock) mock = Mock(spec=Something().smeth) _check(mock) def test_assert_called_once_with(self): mock = Mock() mock() # Will raise an exception if it fails mock.assert_called_once_with() mock() self.assertRaises(AssertionError, mock.assert_called_once_with) mock.reset_mock() self.assertRaises(AssertionError, mock.assert_called_once_with) mock('foo', 'bar', baz=2) mock.assert_called_once_with('foo', 'bar', baz=2) mock.reset_mock() mock('foo', 'bar', baz=2) self.assertRaises( AssertionError, lambda: mock.assert_called_once_with('bob', 'bar', baz=2) ) def test_assert_called_once_with_call_list(self): m = Mock() m(1) m(2) self.assertRaisesRegexp(AssertionError, re.escape("Calls: [call(1), call(2)]"), lambda: m.assert_called_once_with(2)) def test_assert_called_once_with_function_spec(self): def f(a, b, c, d=None): pass mock = Mock(spec=f) mock(1, b=2, c=3) mock.assert_called_once_with(1, 2, 3) mock.assert_called_once_with(a=1, b=2, c=3) self.assertRaises(AssertionError, mock.assert_called_once_with, 1, b=3, c=2) # Expected call doesn't match the spec's signature with self.assertRaises(AssertionError) as cm: mock.assert_called_once_with(e=8) if hasattr(cm.exception, '__cause__'): self.assertIsInstance(cm.exception.__cause__, TypeError) # Mock called more than once => always fails mock(4, 5, 6) self.assertRaises(AssertionError, mock.assert_called_once_with, 1, 2, 3) self.assertRaises(AssertionError, mock.assert_called_once_with, 4, 5, 6) def test_attribute_access_returns_mocks(self): mock = Mock() something = mock.something self.assertTrue(is_instance(something, Mock), "attribute isn't a mock") self.assertEqual(mock.something, something, "different attributes returned for same name") # Usage example mock = Mock() mock.something.return_value = 3 self.assertEqual(mock.something(), 3, "method returned wrong value") self.assertTrue(mock.something.called, "method didn't record being called") def test_attributes_have_name_and_parent_set(self): mock = Mock() something = mock.something self.assertEqual(something._mock_name, "something", "attribute name not set correctly") self.assertEqual(something._mock_parent, mock, "attribute parent not set correctly") def test_method_calls_recorded(self): mock = Mock() mock.something(3, fish=None) mock.something_else.something(6, cake=sentinel.Cake) self.assertEqual(mock.something_else.method_calls, [("something", (6,), {'cake': sentinel.Cake})], "method calls not recorded correctly") self.assertEqual(mock.method_calls, [ ("something", (3,), {'fish': None}), ("something_else.something", (6,), {'cake': sentinel.Cake}) ], "method calls not recorded correctly") def test_method_calls_compare_easily(self): mock = Mock() mock.something() self.assertEqual(mock.method_calls, [('something',)]) self.assertEqual(mock.method_calls, [('something', (), {})]) mock = Mock() mock.something('different') self.assertEqual(mock.method_calls, [('something', ('different',))]) self.assertEqual(mock.method_calls, [('something', ('different',), {})]) mock = Mock() mock.something(x=1) self.assertEqual(mock.method_calls, [('something', {'x': 1})]) self.assertEqual(mock.method_calls, [('something', (), {'x': 1})]) mock = Mock() mock.something('different', some='more') self.assertEqual(mock.method_calls, [ ('something', ('different',), {'some': 'more'}) ]) def test_only_allowed_methods_exist(self): for spec in ['something'], ('something',): for arg in 'spec', 'spec_set': mock = Mock(**{arg: spec}) # this should be allowed mock.something self.assertRaisesRegexp( AttributeError, "Mock object has no attribute 'something_else'", getattr, mock, 'something_else' ) def test_from_spec(self): class Something(object): x = 3 __something__ = None def y(self): pass def test_attributes(mock): # should work mock.x mock.y mock.__something__ self.assertRaisesRegexp( AttributeError, "Mock object has no attribute 'z'", getattr, mock, 'z' ) self.assertRaisesRegexp( AttributeError, "Mock object has no attribute '__foobar__'", getattr, mock, '__foobar__' ) test_attributes(Mock(spec=Something)) test_attributes(Mock(spec=Something())) def test_wraps_calls(self): real = Mock() mock = Mock(wraps=real) self.assertEqual(mock(), real()) real.reset_mock() mock(1, 2, fish=3) real.assert_called_with(1, 2, fish=3) def test_wraps_prevents_automatic_creation_of_mocks(self): class Real(object): pass real = Real() mock = Mock(wraps=real) self.assertRaises(AttributeError, lambda: mock.new_attr()) def test_wraps_call_with_nondefault_return_value(self): real = Mock() mock = Mock(wraps=real) mock.return_value = 3 self.assertEqual(mock(), 3) self.assertFalse(real.called) def test_wraps_attributes(self): class Real(object): attribute = Mock() real = Real() mock = Mock(wraps=real) self.assertEqual(mock.attribute(), real.attribute()) self.assertRaises(AttributeError, lambda: mock.fish) self.assertNotEqual(mock.attribute, real.attribute) result = mock.attribute.frog(1, 2, fish=3) Real.attribute.frog.assert_called_with(1, 2, fish=3) self.assertEqual(result, Real.attribute.frog()) def test_customize_wrapped_object_with_side_effect_iterable_with_default(self): class Real(object): def method(self): return sentinel.ORIGINAL_VALUE real = Real() mock = Mock(wraps=real) mock.method.side_effect = [sentinel.VALUE1, DEFAULT] self.assertEqual(mock.method(), sentinel.VALUE1) self.assertEqual(mock.method(), sentinel.ORIGINAL_VALUE) self.assertRaises(StopIteration, mock.method) def test_customize_wrapped_object_with_side_effect_iterable(self): class Real(object): def method(self): pass real = Real() mock = Mock(wraps=real) mock.method.side_effect = [sentinel.VALUE1, sentinel.VALUE2] self.assertEqual(mock.method(), sentinel.VALUE1) self.assertEqual(mock.method(), sentinel.VALUE2) self.assertRaises(StopIteration, mock.method) def test_customize_wrapped_object_with_side_effect_exception(self): class Real(object): def method(self): pass real = Real() mock = Mock(wraps=real) mock.method.side_effect = RuntimeError self.assertRaises(RuntimeError, mock.method) def test_customize_wrapped_object_with_side_effect_function(self): class Real(object): def method(self): pass def side_effect(): return sentinel.VALUE real = Real() mock = Mock(wraps=real) mock.method.side_effect = side_effect self.assertEqual(mock.method(), sentinel.VALUE) def test_customize_wrapped_object_with_return_value(self): class Real(object): def method(self): pass real = Real() mock = Mock(wraps=real) mock.method.return_value = sentinel.VALUE self.assertEqual(mock.method(), sentinel.VALUE) def test_customize_wrapped_object_with_return_value_and_side_effect(self): # side_effect should always take precedence over return_value. class Real(object): def method(self): pass real = Real() mock = Mock(wraps=real) mock.method.side_effect = [sentinel.VALUE1, sentinel.VALUE2] mock.method.return_value = sentinel.WRONG_VALUE self.assertEqual(mock.method(), sentinel.VALUE1) self.assertEqual(mock.method(), sentinel.VALUE2) self.assertRaises(StopIteration, mock.method) def test_customize_wrapped_object_with_return_value_and_side_effect2(self): # side_effect can return DEFAULT to default to return_value class Real(object): def method(self): pass real = Real() mock = Mock(wraps=real) mock.method.side_effect = lambda: DEFAULT mock.method.return_value = sentinel.VALUE self.assertEqual(mock.method(), sentinel.VALUE) def test_customize_wrapped_object_with_return_value_and_side_effect_default(self): class Real(object): def method(self): pass real = Real() mock = Mock(wraps=real) mock.method.side_effect = [sentinel.VALUE1, DEFAULT] mock.method.return_value = sentinel.RETURN self.assertEqual(mock.method(), sentinel.VALUE1) self.assertEqual(mock.method(), sentinel.RETURN) self.assertRaises(StopIteration, mock.method) def test_exceptional_side_effect(self): mock = Mock(side_effect=AttributeError) self.assertRaises(AttributeError, mock) mock = Mock(side_effect=AttributeError('foo')) self.assertRaises(AttributeError, mock) def test_baseexceptional_side_effect(self): mock = Mock(side_effect=KeyboardInterrupt) self.assertRaises(KeyboardInterrupt, mock) mock = Mock(side_effect=KeyboardInterrupt('foo')) self.assertRaises(KeyboardInterrupt, mock) def test_assert_called_with_message(self): mock = Mock() self.assertRaisesRegexp(AssertionError, 'not called', mock.assert_called_with) def test_assert_called_once_with_message(self): mock = Mock(name='geoffrey') self.assertRaisesRegexp(AssertionError, r"Expected 'geoffrey' to be called once\.", mock.assert_called_once_with) def test__name__(self): mock = Mock() self.assertRaises(AttributeError, lambda: mock.__name__) mock.__name__ = 'foo' self.assertEqual(mock.__name__, 'foo') def test_spec_list_subclass(self): class Sub(list): pass mock = Mock(spec=Sub(['foo'])) mock.append(3) mock.append.assert_called_with(3) self.assertRaises(AttributeError, getattr, mock, 'foo') def test_spec_class(self): class X(object): pass mock = Mock(spec=X) self.assertIsInstance(mock, X) mock = Mock(spec=X()) self.assertIsInstance(mock, X) self.assertIs(mock.__class__, X) self.assertEqual(Mock().__class__.__name__, 'Mock') mock = Mock(spec_set=X) self.assertIsInstance(mock, X) mock = Mock(spec_set=X()) self.assertIsInstance(mock, X) def test_spec_class_no_object_base(self): class X: pass mock = Mock(spec=X) self.assertIsInstance(mock, X) if not six.PY2: # This isn't true on Py2, we should fix if anyone complains: mock = Mock(spec=X()) self.assertIsInstance(mock, X) self.assertIs(mock.__class__, X) self.assertEqual(Mock().__class__.__name__, 'Mock') mock = Mock(spec_set=X) self.assertIsInstance(mock, X) if not six.PY2: # This isn't true on Py2, we should fix if anyone complains: mock = Mock(spec_set=X()) self.assertIsInstance(mock, X) def test_setting_attribute_with_spec_set(self): class X(object): y = 3 mock = Mock(spec=X) mock.x = 'foo' mock = Mock(spec_set=X) def set_attr(): mock.x = 'foo' mock.y = 'foo' self.assertRaises(AttributeError, set_attr) def test_copy(self): current = sys.getrecursionlimit() self.addCleanup(sys.setrecursionlimit, current) # can't use sys.maxint as this doesn't exist in Python 3 sys.setrecursionlimit(int(10e8)) # this segfaults without the fix in place copy.copy(Mock()) @unittest.skipIf(six.PY3, "no old style classes in Python 3") def test_spec_old_style_classes(self): class Foo: bar = 7 mock = Mock(spec=Foo) mock.bar = 6 self.assertRaises(AttributeError, lambda: mock.foo) mock = Mock(spec=Foo()) mock.bar = 6 self.assertRaises(AttributeError, lambda: mock.foo) @unittest.skipIf(six.PY3, "no old style classes in Python 3") def test_spec_set_old_style_classes(self): class Foo: bar = 7 mock = Mock(spec_set=Foo) mock.bar = 6 self.assertRaises(AttributeError, lambda: mock.foo) def _set(): mock.foo = 3 self.assertRaises(AttributeError, _set) mock = Mock(spec_set=Foo()) mock.bar = 6 self.assertRaises(AttributeError, lambda: mock.foo) def _set(): mock.foo = 3 self.assertRaises(AttributeError, _set) def test_subclass_with_properties(self): class SubClass(Mock): def _get(self): return 3 def _set(self, value): raise NameError('strange error') some_attribute = property(_get, _set) s = SubClass(spec_set=SubClass) self.assertEqual(s.some_attribute, 3) def test(): s.some_attribute = 3 self.assertRaises(NameError, test) def test(): s.foo = 'bar' self.assertRaises(AttributeError, test) def test_setting_call(self): mock = Mock() def __call__(self, a): return self._mock_call(a) type(mock).__call__ = __call__ mock('one') mock.assert_called_with('one') self.assertRaises(TypeError, mock, 'one', 'two') def test_dir(self): mock = Mock() attrs = set(dir(mock)) type_attrs = {m for m in dir(Mock) if not m.startswith('_')} # all public attributes from the type are included self.assertEqual(set(), type_attrs - attrs) # creates these attributes mock.a, mock.b self.assertIn('a', dir(mock)) self.assertIn('b', dir(mock)) # instance attributes mock.c = mock.d = None self.assertIn('c', dir(mock)) self.assertIn('d', dir(mock)) # magic methods mock.__iter__ = lambda s: iter([]) self.assertIn('__iter__', dir(mock)) def test_dir_from_spec(self): mock = Mock(spec=unittest.TestCase) testcase_attrs = set(dir(unittest.TestCase)) attrs = set(dir(mock)) # all attributes from the spec are included self.assertEqual(set(), testcase_attrs - attrs) # shadow a sys attribute mock.version = 3 self.assertEqual(dir(mock).count('version'), 1) def test_filter_dir(self): patcher = patch.object(mock, 'FILTER_DIR', False) patcher.start() try: attrs = set(dir(Mock())) type_attrs = set(dir(Mock)) # ALL attributes from the type are included self.assertEqual(set(), type_attrs - attrs) finally: patcher.stop() def test_dir_does_not_include_deleted_attributes(self): mock = Mock() mock.child.return_value = 1 self.assertIn('child', dir(mock)) del mock.child self.assertNotIn('child', dir(mock)) def test_configure_mock(self): mock = Mock(foo='bar') self.assertEqual(mock.foo, 'bar') mock = MagicMock(foo='bar') self.assertEqual(mock.foo, 'bar') kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33, 'foo': MagicMock()} mock = Mock(**kwargs) self.assertRaises(KeyError, mock) self.assertEqual(mock.foo.bar(), 33) self.assertIsInstance(mock.foo, MagicMock) mock = Mock() mock.configure_mock(**kwargs) self.assertRaises(KeyError, mock) self.assertEqual(mock.foo.bar(), 33) self.assertIsInstance(mock.foo, MagicMock) def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs): # needed because assertRaisesRegex doesn't work easily with newlines with self.assertRaises(exception) as context: func(*args, **kwargs) msg = str(context.exception) self.assertEqual(msg, message) def test_assert_called_with_failure_message(self): mock = NonCallableMock() actual = 'not called.' expected = "mock(1, '2', 3, bar='foo')" message = 'expected call not found.\nExpected: %s\nActual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), mock.assert_called_with, 1, '2', 3, bar='foo' ) mock.foo(1, '2', 3, foo='foo') asserters = [ mock.foo.assert_called_with, mock.foo.assert_called_once_with ] for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo(1, '2', 3, bar='foo')" message = 'expected call not found.\nExpected: %s\nActual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth, 1, '2', 3, bar='foo' ) # just kwargs for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo(bar='foo')" message = 'expected call not found.\nExpected: %s\nActual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth, bar='foo' ) # just args for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo(1, 2, 3)" message = 'expected call not found.\nExpected: %s\nActual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth, 1, 2, 3 ) # empty for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo()" message = 'expected call not found.\nExpected: %s\nActual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth ) def test_mock_calls(self): mock = MagicMock() # need to do this because MagicMock.mock_calls used to just return # a MagicMock which also returned a MagicMock when __eq__ was called self.assertIs(mock.mock_calls == [], True) mock = MagicMock() mock() expected = [('', (), {})] self.assertEqual(mock.mock_calls, expected) mock.foo() expected.append(call.foo()) self.assertEqual(mock.mock_calls, expected) # intermediate mock_calls work too self.assertEqual(mock.foo.mock_calls, [('', (), {})]) mock = MagicMock() mock().foo(1, 2, 3, a=4, b=5) expected = [ ('', (), {}), ('().foo', (1, 2, 3), dict(a=4, b=5)) ] self.assertEqual(mock.mock_calls, expected) self.assertEqual(mock.return_value.foo.mock_calls, [('', (1, 2, 3), dict(a=4, b=5))]) self.assertEqual(mock.return_value.mock_calls, [('foo', (1, 2, 3), dict(a=4, b=5))]) mock = MagicMock() mock().foo.bar().baz() expected = [ ('', (), {}), ('().foo.bar', (), {}), ('().foo.bar().baz', (), {}) ] self.assertEqual(mock.mock_calls, expected) self.assertEqual(mock().mock_calls, call.foo.bar().baz().call_list()) for kwargs in dict(), dict(name='bar'): mock = MagicMock(**kwargs) int(mock.foo) expected = [('foo.__int__', (), {})] self.assertEqual(mock.mock_calls, expected) mock = MagicMock(**kwargs) mock.a()() expected = [('a', (), {}), ('a()', (), {})] self.assertEqual(mock.mock_calls, expected) self.assertEqual(mock.a().mock_calls, [call()]) mock = MagicMock(**kwargs) mock(1)(2)(3) self.assertEqual(mock.mock_calls, call(1)(2)(3).call_list()) self.assertEqual(mock().mock_calls, call(2)(3).call_list()) self.assertEqual(mock()().mock_calls, call(3).call_list()) mock = MagicMock(**kwargs) mock(1)(2)(3).a.b.c(4) self.assertEqual(mock.mock_calls, call(1)(2)(3).a.b.c(4).call_list()) self.assertEqual(mock().mock_calls, call(2)(3).a.b.c(4).call_list()) self.assertEqual(mock()().mock_calls, call(3).a.b.c(4).call_list()) mock = MagicMock(**kwargs) int(mock().foo.bar().baz()) last_call = ('().foo.bar().baz().__int__', (), {}) self.assertEqual(mock.mock_calls[-1], last_call) self.assertEqual(mock().mock_calls, call.foo.bar().baz().__int__().call_list()) self.assertEqual(mock().foo.bar().mock_calls, call.baz().__int__().call_list()) self.assertEqual(mock().foo.bar().baz.mock_calls, call().__int__().call_list()) def test_child_mock_call_equal(self): m = Mock() result = m() result.wibble() # parent looks like this: self.assertEqual(m.mock_calls, [call(), call().wibble()]) # but child should look like this: self.assertEqual(result.mock_calls, [call.wibble()]) def test_mock_call_not_equal_leaf(self): m = Mock() m.foo().something() self.assertNotEqual(m.mock_calls[1], call.foo().different()) self.assertEqual(m.mock_calls[0], call.foo()) def test_mock_call_not_equal_non_leaf(self): m = Mock() m.foo().bar() self.assertNotEqual(m.mock_calls[1], call.baz().bar()) self.assertNotEqual(m.mock_calls[0], call.baz()) def test_mock_call_not_equal_non_leaf_params_different(self): m = Mock() m.foo(x=1).bar() # This isn't ideal, but there's no way to fix it without breaking backwards compatibility: self.assertEqual(m.mock_calls[1], call.foo(x=2).bar()) def test_mock_call_not_equal_non_leaf_attr(self): m = Mock() m.foo.bar() self.assertNotEqual(m.mock_calls[0], call.baz.bar()) def test_mock_call_not_equal_non_leaf_call_versus_attr(self): m = Mock() m.foo.bar() self.assertNotEqual(m.mock_calls[0], call.foo().bar()) def test_mock_call_repr(self): m = Mock() m.foo().bar().baz.bob() self.assertEqual(repr(m.mock_calls[0]), 'call.foo()') self.assertEqual(repr(m.mock_calls[1]), 'call.foo().bar()') self.assertEqual(repr(m.mock_calls[2]), 'call.foo().bar().baz.bob()') def test_mock_call_repr_loop(self): m = Mock() m.foo = m repr(m.foo()) self.assertRegexpMatches(repr(m.foo()), r"") def test_mock_calls_contains(self): m = Mock() self.assertFalse([call()] in m.mock_calls) def test_subclassing(self): class Subclass(Mock): pass mock = Subclass() self.assertIsInstance(mock.foo, Subclass) self.assertIsInstance(mock(), Subclass) class Subclass(Mock): def _get_child_mock(self, **kwargs): return Mock(**kwargs) mock = Subclass() self.assertNotIsInstance(mock.foo, Subclass) self.assertNotIsInstance(mock(), Subclass) def test_arg_lists(self): mocks = [ Mock(), MagicMock(), NonCallableMock(), NonCallableMagicMock() ] def assert_attrs(mock): names = 'call_args_list', 'method_calls', 'mock_calls' for name in names: attr = getattr(mock, name) self.assertIsInstance(attr, _CallList) self.assertIsInstance(attr, list) self.assertEqual(attr, []) for mock in mocks: assert_attrs(mock) if callable(mock): mock() mock(1, 2) mock(a=3) mock.reset_mock() assert_attrs(mock) mock.foo() mock.foo.bar(1, a=3) mock.foo(1).bar().baz(3) mock.reset_mock() assert_attrs(mock) def test_call_args_two_tuple(self): mock = Mock() mock(1, a=3) mock(2, b=4) self.assertEqual(len(mock.call_args), 2) self.assertEqual(mock.call_args.args, (2,)) self.assertEqual(mock.call_args.kwargs, dict(b=4)) expected_list = [((1,), dict(a=3)), ((2,), dict(b=4))] for expected, call_args in zip(expected_list, mock.call_args_list): self.assertEqual(len(call_args), 2) self.assertEqual(expected[0], call_args[0]) self.assertEqual(expected[1], call_args[1]) def test_side_effect_iterator(self): mock = Mock(side_effect=iter([1, 2, 3])) self.assertEqual([mock(), mock(), mock()], [1, 2, 3]) self.assertRaises(StopIteration, mock) mock = MagicMock(side_effect=['a', 'b', 'c']) self.assertEqual([mock(), mock(), mock()], ['a', 'b', 'c']) self.assertRaises(StopIteration, mock) mock = Mock(side_effect='ghi') self.assertEqual([mock(), mock(), mock()], ['g', 'h', 'i']) self.assertRaises(StopIteration, mock) class Foo(object): pass mock = MagicMock(side_effect=Foo) self.assertIsInstance(mock(), Foo) mock = Mock(side_effect=Iter()) self.assertEqual([mock(), mock(), mock(), mock()], ['this', 'is', 'an', 'iter']) self.assertRaises(StopIteration, mock) def test_side_effect_setting_iterator(self): mock = Mock() mock.side_effect = iter([1, 2, 3]) self.assertEqual([mock(), mock(), mock()], [1, 2, 3]) self.assertRaises(StopIteration, mock) side_effect = mock.side_effect self.assertIsInstance(side_effect, type(iter([]))) mock.side_effect = ['a', 'b', 'c'] self.assertEqual([mock(), mock(), mock()], ['a', 'b', 'c']) self.assertRaises(StopIteration, mock) side_effect = mock.side_effect self.assertIsInstance(side_effect, type(iter([]))) this_iter = Iter() mock.side_effect = this_iter self.assertEqual([mock(), mock(), mock(), mock()], ['this', 'is', 'an', 'iter']) self.assertRaises(StopIteration, mock) self.assertIs(mock.side_effect, this_iter) def test_side_effect_iterator_exceptions(self): for Klass in Mock, MagicMock: iterable = (ValueError, 3, KeyError, 6) m = Klass(side_effect=iterable) self.assertRaises(ValueError, m) self.assertEqual(m(), 3) self.assertRaises(KeyError, m) self.assertEqual(m(), 6) def test_side_effect_iterator_default(self): mock = Mock(return_value=2) mock.side_effect = iter([1, DEFAULT]) self.assertEqual([mock(), mock()], [1, 2]) def test_assert_has_calls_any_order(self): mock = Mock() mock(1, 2) mock(a=3) mock(3, 4) mock(b=6) mock(b=6) kalls = [ call(1, 2), ({'a': 3},), ((3, 4),), ((), {'a': 3}), ('', (1, 2)), ('', {'a': 3}), ('', (1, 2), {}), ('', (), {'a': 3}) ] for kall in kalls: mock.assert_has_calls([kall], any_order=True) for kall in call(1, '2'), call(b=3), call(), 3, None, 'foo': self.assertRaises( AssertionError, mock.assert_has_calls, [kall], any_order=True ) kall_lists = [ [call(1, 2), call(b=6)], [call(3, 4), call(1, 2)], [call(b=6), call(b=6)], ] for kall_list in kall_lists: mock.assert_has_calls(kall_list, any_order=True) kall_lists = [ [call(b=6), call(b=6), call(b=6)], [call(1, 2), call(1, 2)], [call(3, 4), call(1, 2), call(5, 7)], [call(b=6), call(3, 4), call(b=6), call(1, 2), call(b=6)], ] for kall_list in kall_lists: self.assertRaises( AssertionError, mock.assert_has_calls, kall_list, any_order=True ) def test_assert_has_calls(self): kalls1 = [ call(1, 2), ({'a': 3},), ((3, 4),), call(b=6), ('', (1,), {'b': 6}), ] kalls2 = [call.foo(), call.bar(1)] kalls2.extend(call.spam().baz(a=3).call_list()) kalls2.extend(call.bam(set(), foo={}).fish([1]).call_list()) mocks = [] for mock in Mock(), MagicMock(): mock(1, 2) mock(a=3) mock(3, 4) mock(b=6) mock(1, b=6) mocks.append((mock, kalls1)) mock = Mock() mock.foo() mock.bar(1) mock.spam().baz(a=3) mock.bam(set(), foo={}).fish([1]) mocks.append((mock, kalls2)) for mock, kalls in mocks: for i in range(len(kalls)): for step in 1, 2, 3: these = kalls[i:i+step] mock.assert_has_calls(these) if len(these) > 1: self.assertRaises( AssertionError, mock.assert_has_calls, list(reversed(these)) ) def test_assert_has_calls_with_function_spec(self): def f(a, b, c, d=None): pass mock = Mock(spec=f) mock(1, b=2, c=3) mock(4, 5, c=6, d=7) mock(10, 11, c=12) calls = [ ('', (1, 2, 3), {}), ('', (4, 5, 6), {'d': 7}), ((10, 11, 12), {}), ] mock.assert_has_calls(calls) mock.assert_has_calls(calls, any_order=True) mock.assert_has_calls(calls[1:]) mock.assert_has_calls(calls[1:], any_order=True) mock.assert_has_calls(calls[:-1]) mock.assert_has_calls(calls[:-1], any_order=True) # Reversed order calls = list(reversed(calls)) with self.assertRaises(AssertionError): mock.assert_has_calls(calls) mock.assert_has_calls(calls, any_order=True) with self.assertRaises(AssertionError): mock.assert_has_calls(calls[1:]) mock.assert_has_calls(calls[1:], any_order=True) with self.assertRaises(AssertionError): mock.assert_has_calls(calls[:-1]) mock.assert_has_calls(calls[:-1], any_order=True) def test_assert_any_call(self): mock = Mock() mock(1, 2) mock(a=3) mock(1, b=6) mock.assert_any_call(1, 2) mock.assert_any_call(a=3) mock.assert_any_call(1, b=6) self.assertRaises( AssertionError, mock.assert_any_call ) self.assertRaises( AssertionError, mock.assert_any_call, 1, 3 ) self.assertRaises( AssertionError, mock.assert_any_call, a=4 ) def test_assert_any_call_with_function_spec(self): def f(a, b, c, d=None): pass mock = Mock(spec=f) mock(1, b=2, c=3) mock(4, 5, c=6, d=7) mock.assert_any_call(1, 2, 3) mock.assert_any_call(a=1, b=2, c=3) mock.assert_any_call(4, 5, 6, 7) mock.assert_any_call(a=4, b=5, c=6, d=7) self.assertRaises(AssertionError, mock.assert_any_call, 1, b=3, c=2) # Expected call doesn't match the spec's signature with self.assertRaises(AssertionError) as cm: mock.assert_any_call(e=8) if hasattr(cm.exception, '__cause__'): self.assertIsInstance(cm.exception.__cause__, TypeError) def test_mock_calls_create_autospec(self): def f(a, b): pass obj = Iter() obj.f = f funcs = [ create_autospec(f), create_autospec(obj).f ] for func in funcs: func(1, 2) func(3, 4) self.assertEqual( func.mock_calls, [call(1, 2), call(3, 4)] ) #Issue21222 def test_create_autospec_with_name(self): m = mock.create_autospec(object(), name='sweet_func') self.assertIn('sweet_func', repr(m)) #Issue23078 def test_create_autospec_classmethod_and_staticmethod(self): class TestClass: @classmethod def class_method(cls): pass @staticmethod def static_method(): pass for method in ('class_method', 'static_method'): mock_method = mock.create_autospec(getattr(TestClass, method)) mock_method() mock_method.assert_called_once_with() self.assertRaises(TypeError, mock_method, 'extra_arg') #Issue21238 def test_mock_unsafe(self): m = Mock() with self.assertRaises(AttributeError): m.assert_foo_call() with self.assertRaises(AttributeError): m.assret_foo_call() m = Mock(unsafe=True) m.assert_foo_call() m.assret_foo_call() #Issue21262 def test_assert_not_called(self): m = Mock() m.hello.assert_not_called() m.hello() with self.assertRaises(AssertionError): m.hello.assert_not_called() def test_assert_not_called_message(self): m = Mock() m(1, 2) self.assertRaisesRegexp(AssertionError, re.escape("Calls: [call(1, 2)]"), m.assert_not_called) def test_assert_called(self): m = Mock() with self.assertRaises(AssertionError): m.hello.assert_called() m.hello() m.hello.assert_called() m.hello() m.hello.assert_called() def test_assert_called_once(self): m = Mock() with self.assertRaises(AssertionError): m.hello.assert_called_once() m.hello() m.hello.assert_called_once() m.hello() with self.assertRaises(AssertionError): m.hello.assert_called_once() def test_assert_called_once_message(self): m = Mock() m(1, 2) m(3) self.assertRaisesRegexp(AssertionError, re.escape("Calls: [call(1, 2), call(3)]"), m.assert_called_once) def test_assert_called_once_message_not_called(self): m = Mock() with self.assertRaises(AssertionError) as e: m.assert_called_once() self.assertNotIn("Calls:", str(e.exception)) #Issue21256 printout of keyword args should be in deterministic order def test_sorted_call_signature(self): m = Mock() m.hello(name='hello', daddy='hero') text = "call(daddy='hero', name='hello')" self.assertEqual(repr(m.hello.call_args), text) #Issue21270 overrides tuple methods for mock.call objects def test_override_tuple_methods(self): c = call.count() i = call.index(132,'hello') m = Mock() m.count() m.index(132,"hello") self.assertEqual(m.method_calls[0], c) self.assertEqual(m.method_calls[1], i) def test_reset_return_sideeffect(self): m = Mock(return_value=10, side_effect=[2,3]) m.reset_mock(return_value=True, side_effect=True) self.assertIsInstance(m.return_value, Mock) self.assertEqual(m.side_effect, None) def test_reset_return(self): m = Mock(return_value=10, side_effect=[2,3]) m.reset_mock(return_value=True) self.assertIsInstance(m.return_value, Mock) self.assertNotEqual(m.side_effect, None) def test_reset_sideeffect(self): m = Mock(return_value=10, side_effect=[2,3]) m.reset_mock(side_effect=True) self.assertEqual(m.return_value, 10) self.assertEqual(m.side_effect, None) def test_mock_add_spec(self): class _One(object): one = 1 class _Two(object): two = 2 class Anything(object): one = two = three = 'four' klasses = [ Mock, MagicMock, NonCallableMock, NonCallableMagicMock ] for Klass in list(klasses): klasses.append(lambda K=Klass: K(spec=Anything)) klasses.append(lambda K=Klass: K(spec_set=Anything)) for Klass in klasses: for kwargs in dict(), dict(spec_set=True): mock = Klass() #no error mock.one, mock.two, mock.three for One, Two in [(_One, _Two), (['one'], ['two'])]: for kwargs in dict(), dict(spec_set=True): mock.mock_add_spec(One, **kwargs) mock.one self.assertRaises( AttributeError, getattr, mock, 'two' ) self.assertRaises( AttributeError, getattr, mock, 'three' ) if 'spec_set' in kwargs: self.assertRaises( AttributeError, setattr, mock, 'three', None ) mock.mock_add_spec(Two, **kwargs) self.assertRaises( AttributeError, getattr, mock, 'one' ) mock.two self.assertRaises( AttributeError, getattr, mock, 'three' ) if 'spec_set' in kwargs: self.assertRaises( AttributeError, setattr, mock, 'three', None ) # note that creating a mock, setting an instance attribute, and # *then* setting a spec doesn't work. Not the intended use case def test_mock_add_spec_magic_methods(self): for Klass in MagicMock, NonCallableMagicMock: mock = Klass() int(mock) mock.mock_add_spec(object) self.assertRaises(TypeError, int, mock) mock = Klass() mock['foo'] mock.__int__.return_value =4 mock.mock_add_spec(int) self.assertEqual(int(mock), 4) self.assertRaises(TypeError, lambda: mock['foo']) def test_adding_child_mock(self): for Klass in NonCallableMock, Mock, MagicMock, NonCallableMagicMock: mock = Klass() mock.foo = Mock() mock.foo() self.assertEqual(mock.method_calls, [call.foo()]) self.assertEqual(mock.mock_calls, [call.foo()]) mock = Klass() mock.bar = Mock(name='name') mock.bar() self.assertEqual(mock.method_calls, []) self.assertEqual(mock.mock_calls, []) # mock with an existing _new_parent but no name mock = Klass() mock.baz = MagicMock()() mock.baz() self.assertEqual(mock.method_calls, []) self.assertEqual(mock.mock_calls, []) def test_adding_return_value_mock(self): for Klass in Mock, MagicMock: mock = Klass() mock.return_value = MagicMock() mock()() self.assertEqual(mock.mock_calls, [call(), call()()]) def test_manager_mock(self): class Foo(object): one = 'one' two = 'two' manager = Mock() p1 = patch.object(Foo, 'one') p2 = patch.object(Foo, 'two') mock_one = p1.start() self.addCleanup(p1.stop) mock_two = p2.start() self.addCleanup(p2.stop) manager.attach_mock(mock_one, 'one') manager.attach_mock(mock_two, 'two') Foo.two() Foo.one() self.assertEqual(manager.mock_calls, [call.two(), call.one()]) def test_magic_methods_mock_calls(self): for Klass in Mock, MagicMock: m = Klass() m.__int__ = Mock(return_value=3) m.__float__ = MagicMock(return_value=3.0) int(m) float(m) self.assertEqual(m.mock_calls, [call.__int__(), call.__float__()]) self.assertEqual(m.method_calls, []) def test_mock_open_reuse_issue_21750(self): mocked_open = mock.mock_open(read_data='data') f1 = mocked_open('a-name') f1_data = f1.read() f2 = mocked_open('another-name') f2_data = f2.read() self.assertEqual(f1_data, f2_data) def test_mock_open_dunder_iter_issue(self): # Test dunder_iter method generates the expected result and # consumes the iterator. mocked_open = mock.mock_open(read_data='Remarkable\nNorwegian Blue') f1 = mocked_open('a-name') lines = [line for line in f1] self.assertEqual(lines[0], 'Remarkable\n') self.assertEqual(lines[1], 'Norwegian Blue') self.assertEqual(list(f1), []) def test_mock_open_write(self): # Test exception in file writing write() mock_namedtemp = mock.mock_open(mock.MagicMock(name='JLV')) with mock.patch('tempfile.NamedTemporaryFile', mock_namedtemp): mock_filehandle = mock_namedtemp.return_value mock_write = mock_filehandle.write mock_write.side_effect = OSError('Test 2 Error') def attempt(): tempfile.NamedTemporaryFile().write('asd') self.assertRaises(OSError, attempt) def test_mock_open_alter_readline(self): mopen = mock.mock_open(read_data='foo\nbarn') mopen.return_value.readline.side_effect = lambda *args:'abc' first = mopen().readline() second = mopen().readline() self.assertEqual('abc', first) self.assertEqual('abc', second) def test_mock_open_after_eof(self): # read, readline and readlines should work after end of file. _open = mock.mock_open(read_data='foo') h = _open('bar') h.read() self.assertEqual('', h.read()) self.assertEqual('', h.read()) self.assertEqual('', h.readline()) self.assertEqual('', h.readline()) self.assertEqual([], h.readlines()) self.assertEqual([], h.readlines()) def test_mock_parents(self): for Klass in Mock, MagicMock: m = Klass() original_repr = repr(m) m.return_value = m self.assertIs(m(), m) self.assertEqual(repr(m), original_repr) m.reset_mock() self.assertIs(m(), m) self.assertEqual(repr(m), original_repr) m = Klass() m.b = m.a self.assertIn("name='mock.a'", repr(m.b)) self.assertIn("name='mock.a'", repr(m.a)) m.reset_mock() self.assertIn("name='mock.a'", repr(m.b)) self.assertIn("name='mock.a'", repr(m.a)) m = Klass() original_repr = repr(m) m.a = m() m.a.return_value = m self.assertEqual(repr(m), original_repr) self.assertEqual(repr(m.a()), original_repr) def test_attach_mock(self): classes = Mock, MagicMock, NonCallableMagicMock, NonCallableMock for Klass in classes: for Klass2 in classes: m = Klass() m2 = Klass2(name='foo') m.attach_mock(m2, 'bar') self.assertIs(m.bar, m2) self.assertIn("name='mock.bar'", repr(m2)) m.bar.baz(1) self.assertEqual(m.mock_calls, [call.bar.baz(1)]) self.assertEqual(m.method_calls, [call.bar.baz(1)]) def test_attach_mock_return_value(self): classes = Mock, MagicMock, NonCallableMagicMock, NonCallableMock for Klass in Mock, MagicMock: for Klass2 in classes: m = Klass() m2 = Klass2(name='foo') m.attach_mock(m2, 'return_value') self.assertIs(m(), m2) self.assertIn("name='mock()'", repr(m2)) m2.foo() self.assertEqual(m.mock_calls, call().foo().call_list()) def test_attribute_deletion(self): for mock in (Mock(), MagicMock(), NonCallableMagicMock(), NonCallableMock()): self.assertTrue(hasattr(mock, 'm')) del mock.m self.assertFalse(hasattr(mock, 'm')) del mock.f self.assertFalse(hasattr(mock, 'f')) self.assertRaises(AttributeError, getattr, mock, 'f') def test_mock_does_not_raise_on_repeated_attribute_deletion(self): # bpo-20239: Assigning and deleting twice an attribute raises. for mock in (Mock(), MagicMock(), NonCallableMagicMock(), NonCallableMock()): mock.foo = 3 self.assertTrue(hasattr(mock, 'foo')) self.assertEqual(mock.foo, 3) del mock.foo self.assertFalse(hasattr(mock, 'foo')) mock.foo = 4 self.assertTrue(hasattr(mock, 'foo')) self.assertEqual(mock.foo, 4) del mock.foo self.assertFalse(hasattr(mock, 'foo')) def test_mock_raises_when_deleting_nonexistent_attribute(self): for mock in (Mock(), MagicMock(), NonCallableMagicMock(), NonCallableMock()): del mock.foo with self.assertRaises(AttributeError): del mock.foo def test_reset_mock_does_not_raise_on_attr_deletion(self): # bpo-31177: reset_mock should not raise AttributeError when attributes # were deleted in a mock instance mock = Mock() mock.child = True del mock.child mock.reset_mock() self.assertFalse(hasattr(mock, 'child')) def test_class_assignable(self): for mock in Mock(), MagicMock(): self.assertNotIsInstance(mock, int) mock.__class__ = int self.assertIsInstance(mock, int) mock.foo def test_name_attribute_of_call(self): # bpo-35357: _Call should not disclose any attributes whose names # may clash with popular ones (such as ".name") self.assertIsNotNone(call.name) self.assertEqual(type(call.name), _Call) self.assertEqual(type(call.name().name), _Call) def test_parent_attribute_of_call(self): # bpo-35357: _Call should not disclose any attributes whose names # may clash with popular ones (such as ".parent") self.assertIsNotNone(call.parent) self.assertEqual(type(call.parent), _Call) self.assertEqual(type(call.parent().parent), _Call) def test_parent_propagation_with_create_autospec(self): def foo(a, b): pass mock = Mock() mock.child = create_autospec(foo) mock.child(1, 2) self.assertRaises(TypeError, mock.child, 1) self.assertEqual(mock.mock_calls, [call.child(1, 2)]) def test_isinstance_under_settrace(self): # bpo-36593 : __class__ is not set for a class that has __class__ # property defined when it's used with sys.settrace(trace) set. # Delete the module to force reimport with tracing function set # restore the old reference later since there are other tests that are # dependent on unittest.mock.patch. In testpatch.PatchTest # test_patch_dict_test_prefix and test_patch_test_prefix not restoring # causes the objects patched to go out of sync old_patch = mock.patch # Directly using __setattr__ on unittest.mock causes current imported # reference to be updated. Use a lambda so that during cleanup the # re-imported new reference is updated. self.addCleanup(lambda patch: setattr(mock, 'patch', patch), old_patch) with patch.dict('sys.modules'): del sys.modules['mock.mock'] # This trace will stop coverage being measured ;-) def trace(frame, event, arg): # pragma: no cover return trace self.addCleanup(sys.settrace, sys.gettrace()) sys.settrace(trace) from mock.mock import ( Mock, MagicMock, NonCallableMock, NonCallableMagicMock ) mocks = [ Mock, MagicMock, NonCallableMock, NonCallableMagicMock ] for mock_ in mocks: obj = mock_(spec=Something) self.assertIsInstance(obj, Something) if __name__ == '__main__': unittest.main() mock-3.0.5/mock/tests/testpatch.py000066400000000000000000001577341346437275100171510ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ import os import sys import six import unittest from mock.tests import support from mock.tests.support import SomeClass, is_instance, uncache from mock import ( NonCallableMock, CallableMixin, patch, sentinel, MagicMock, Mock, NonCallableMagicMock, DEFAULT, call ) from mock.mock import _patch, _get_target builtin_string = '__builtin__' if six.PY3: builtin_string = 'builtins' unicode = str PTModule = sys.modules[__name__] MODNAME = '%s.PTModule' % __name__ def _get_proxy(obj, get_only=True): class Proxy(object): def __getattr__(self, name): return getattr(obj, name) if not get_only: def __setattr__(self, name, value): setattr(obj, name, value) def __delattr__(self, name): delattr(obj, name) Proxy.__setattr__ = __setattr__ Proxy.__delattr__ = __delattr__ return Proxy() # for use in the test something = sentinel.Something something_else = sentinel.SomethingElse class Foo(object): def __init__(self, a): pass def f(self, a): pass def g(self): pass foo = 'bar' @staticmethod def static_method(): pass @classmethod def class_method(cls): pass class Bar(object): def a(self): pass foo_name = '%s.Foo' % __name__ def function(a, b=Foo): pass class Container(object): def __init__(self): self.values = {} def __getitem__(self, name): return self.values[name] def __setitem__(self, name, value): self.values[name] = value def __delitem__(self, name): del self.values[name] def __iter__(self): return iter(self.values) class PatchTest(unittest.TestCase): def assertNotCallable(self, obj, magic=True): MockClass = NonCallableMagicMock if not magic: MockClass = NonCallableMock self.assertRaises(TypeError, obj) self.assertTrue(is_instance(obj, MockClass)) self.assertFalse(is_instance(obj, CallableMixin)) def test_single_patchobject(self): class Something(object): attribute = sentinel.Original @patch.object(Something, 'attribute', sentinel.Patched) def test(): self.assertEqual(Something.attribute, sentinel.Patched, "unpatched") test() self.assertEqual(Something.attribute, sentinel.Original, "patch not restored") def test_patchobject_with_none(self): class Something(object): attribute = sentinel.Original @patch.object(Something, 'attribute', None) def test(): self.assertIsNone(Something.attribute, "unpatched") test() self.assertEqual(Something.attribute, sentinel.Original, "patch not restored") def test_multiple_patchobject(self): class Something(object): attribute = sentinel.Original next_attribute = sentinel.Original2 @patch.object(Something, 'attribute', sentinel.Patched) @patch.object(Something, 'next_attribute', sentinel.Patched2) def test(): self.assertEqual(Something.attribute, sentinel.Patched, "unpatched") self.assertEqual(Something.next_attribute, sentinel.Patched2, "unpatched") test() self.assertEqual(Something.attribute, sentinel.Original, "patch not restored") self.assertEqual(Something.next_attribute, sentinel.Original2, "patch not restored") def test_object_lookup_is_quite_lazy(self): global something original = something @patch('%s.something' % __name__, sentinel.Something2) def test(): pass try: something = sentinel.replacement_value test() self.assertEqual(something, sentinel.replacement_value) finally: something = original def test_patch(self): @patch('%s.something' % __name__, sentinel.Something2) def test(): self.assertEqual(PTModule.something, sentinel.Something2, "unpatched") test() self.assertEqual(PTModule.something, sentinel.Something, "patch not restored") @patch('%s.something' % __name__, sentinel.Something2) @patch('%s.something_else' % __name__, sentinel.SomethingElse) def test(): self.assertEqual(PTModule.something, sentinel.Something2, "unpatched") self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "unpatched") self.assertEqual(PTModule.something, sentinel.Something, "patch not restored") self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "patch not restored") # Test the patching and restoring works a second time test() self.assertEqual(PTModule.something, sentinel.Something, "patch not restored") self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "patch not restored") mock = Mock() mock.return_value = sentinel.Handle @patch('%s.open' % builtin_string, mock) def test(): self.assertEqual(open('filename', 'r'), sentinel.Handle, "open not patched") test() test() self.assertNotEqual(open, mock, "patch not restored") def test_patch_class_attribute(self): @patch('%s.SomeClass.class_attribute' % __name__, sentinel.ClassAttribute) def test(): self.assertEqual(PTModule.SomeClass.class_attribute, sentinel.ClassAttribute, "unpatched") test() self.assertIsNone(PTModule.SomeClass.class_attribute, "patch not restored") def test_patchobject_with_default_mock(self): class Test(object): something = sentinel.Original something2 = sentinel.Original2 @patch.object(Test, 'something') def test(mock): self.assertEqual(mock, Test.something, "Mock not passed into test function") self.assertIsInstance(mock, MagicMock, "patch with two arguments did not create a mock") test() @patch.object(Test, 'something') @patch.object(Test, 'something2') def test(this1, this2, mock1, mock2): self.assertEqual(this1, sentinel.this1, "Patched function didn't receive initial argument") self.assertEqual(this2, sentinel.this2, "Patched function didn't receive second argument") self.assertEqual(mock1, Test.something2, "Mock not passed into test function") self.assertEqual(mock2, Test.something, "Second Mock not passed into test function") self.assertIsInstance(mock2, MagicMock, "patch with two arguments did not create a mock") self.assertIsInstance(mock2, MagicMock, "patch with two arguments did not create a mock") # A hack to test that new mocks are passed the second time self.assertNotEqual(outerMock1, mock1, "unexpected value for mock1") self.assertNotEqual(outerMock2, mock2, "unexpected value for mock1") return mock1, mock2 outerMock1 = outerMock2 = None outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2) # Test that executing a second time creates new mocks test(sentinel.this1, sentinel.this2) def test_patch_with_spec(self): @patch('%s.SomeClass' % __name__, spec=SomeClass) def test(MockSomeClass): self.assertEqual(SomeClass, MockSomeClass) self.assertTrue(is_instance(SomeClass.wibble, MagicMock)) self.assertRaises(AttributeError, lambda: SomeClass.not_wibble) test() def test_patchobject_with_spec(self): @patch.object(SomeClass, 'class_attribute', spec=SomeClass) def test(MockAttribute): self.assertEqual(SomeClass.class_attribute, MockAttribute) self.assertTrue(is_instance(SomeClass.class_attribute.wibble, MagicMock)) self.assertRaises(AttributeError, lambda: SomeClass.class_attribute.not_wibble) test() def test_patch_with_spec_as_list(self): @patch('%s.SomeClass' % __name__, spec=['wibble']) def test(MockSomeClass): self.assertEqual(SomeClass, MockSomeClass) self.assertTrue(is_instance(SomeClass.wibble, MagicMock)) self.assertRaises(AttributeError, lambda: SomeClass.not_wibble) test() def test_patchobject_with_spec_as_list(self): @patch.object(SomeClass, 'class_attribute', spec=['wibble']) def test(MockAttribute): self.assertEqual(SomeClass.class_attribute, MockAttribute) self.assertTrue(is_instance(SomeClass.class_attribute.wibble, MagicMock)) self.assertRaises(AttributeError, lambda: SomeClass.class_attribute.not_wibble) test() def test_nested_patch_with_spec_as_list(self): # regression test for nested decorators @patch('%s.open' % builtin_string) @patch('%s.SomeClass' % __name__, spec=['wibble']) def test(MockSomeClass, MockOpen): self.assertEqual(SomeClass, MockSomeClass) self.assertTrue(is_instance(SomeClass.wibble, MagicMock)) self.assertRaises(AttributeError, lambda: SomeClass.not_wibble) test() def test_patch_with_spec_as_boolean(self): @patch('%s.SomeClass' % __name__, spec=True) def test(MockSomeClass): self.assertEqual(SomeClass, MockSomeClass) # Should not raise attribute error MockSomeClass.wibble self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble) test() def test_patch_object_with_spec_as_boolean(self): @patch.object(PTModule, 'SomeClass', spec=True) def test(MockSomeClass): self.assertEqual(SomeClass, MockSomeClass) # Should not raise attribute error MockSomeClass.wibble self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble) test() def test_patch_class_acts_with_spec_is_inherited(self): @patch('%s.SomeClass' % __name__, spec=True) def test(MockSomeClass): self.assertTrue(is_instance(MockSomeClass, MagicMock)) instance = MockSomeClass() self.assertNotCallable(instance) # Should not raise attribute error instance.wibble self.assertRaises(AttributeError, lambda: instance.not_wibble) test() def test_patch_with_create_mocks_non_existent_attributes(self): @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True) def test(): self.assertEqual(frooble, sentinel.Frooble) test() self.assertRaises(NameError, lambda: frooble) def test_patchobject_with_create_mocks_non_existent_attributes(self): @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True) def test(): self.assertEqual(SomeClass.frooble, sentinel.Frooble) test() self.assertFalse(hasattr(SomeClass, 'frooble')) def test_patch_wont_create_by_default(self): with self.assertRaises(AttributeError): @patch('%s.frooble' % builtin_string, sentinel.Frooble) def test(): pass test() self.assertRaises(NameError, lambda: frooble) def test_patchobject_wont_create_by_default(self): with self.assertRaises(AttributeError): @patch.object(SomeClass, 'ord', sentinel.Frooble) def test(): pass test() self.assertFalse(hasattr(SomeClass, 'ord')) def test_patch_builtins_without_create(self): @patch(__name__+'.ord') def test_ord(mock_ord): mock_ord.return_value = 101 return ord('c') @patch(__name__+'.open') def test_open(mock_open): m = mock_open.return_value m.read.return_value = 'abcd' fobj = open('doesnotexists.txt') data = fobj.read() fobj.close() return data self.assertEqual(test_ord(), 101) self.assertEqual(test_open(), 'abcd') def test_patch_with_static_methods(self): class Foo(object): @staticmethod def woot(): return sentinel.Static @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched)) def anonymous(): self.assertEqual(Foo.woot(), sentinel.Patched) anonymous() self.assertEqual(Foo.woot(), sentinel.Static) def test_patch_local(self): foo = sentinel.Foo @patch.object(sentinel, 'Foo', 'Foo') def anonymous(): self.assertEqual(sentinel.Foo, 'Foo') anonymous() self.assertEqual(sentinel.Foo, foo) def test_patch_slots(self): class Foo(object): __slots__ = ('Foo',) foo = Foo() foo.Foo = sentinel.Foo @patch.object(foo, 'Foo', 'Foo') def anonymous(): self.assertEqual(foo.Foo, 'Foo') anonymous() self.assertEqual(foo.Foo, sentinel.Foo) def test_patchobject_class_decorator(self): class Something(object): attribute = sentinel.Original class Foo(object): def test_method(other_self): self.assertEqual(Something.attribute, sentinel.Patched, "unpatched") def not_test_method(other_self): self.assertEqual(Something.attribute, sentinel.Original, "non-test method patched") Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo) f = Foo() f.test_method() f.not_test_method() self.assertEqual(Something.attribute, sentinel.Original, "patch not restored") def test_patch_class_decorator(self): class Something(object): attribute = sentinel.Original class Foo(object): test_class_attr = 'whatever' def test_method(other_self, mock_something): self.assertEqual(PTModule.something, mock_something, "unpatched") def not_test_method(other_self): self.assertEqual(PTModule.something, sentinel.Something, "non-test method patched") Foo = patch('%s.something' % __name__)(Foo) f = Foo() f.test_method() f.not_test_method() self.assertEqual(Something.attribute, sentinel.Original, "patch not restored") self.assertEqual(PTModule.something, sentinel.Something, "patch not restored") def test_patchobject_twice(self): class Something(object): attribute = sentinel.Original next_attribute = sentinel.Original2 @patch.object(Something, 'attribute', sentinel.Patched) @patch.object(Something, 'attribute', sentinel.Patched) def test(): self.assertEqual(Something.attribute, sentinel.Patched, "unpatched") test() self.assertEqual(Something.attribute, sentinel.Original, "patch not restored") def test_patch_dict(self): foo = {'initial': object(), 'other': 'something'} original = foo.copy() @patch.dict(foo) def test(): foo['a'] = 3 del foo['initial'] foo['other'] = 'something else' test() self.assertEqual(foo, original) @patch.dict(foo, {'a': 'b'}) def test(): self.assertEqual(len(foo), 3) self.assertEqual(foo['a'], 'b') test() self.assertEqual(foo, original) @patch.dict(foo, [('a', 'b')]) def test(): self.assertEqual(len(foo), 3) self.assertEqual(foo['a'], 'b') test() self.assertEqual(foo, original) def test_patch_dict_with_container_object(self): foo = Container() foo['initial'] = object() foo['other'] = 'something' original = foo.values.copy() @patch.dict(foo) def test(): foo['a'] = 3 del foo['initial'] foo['other'] = 'something else' test() self.assertEqual(foo.values, original) @patch.dict(foo, {'a': 'b'}) def test(): self.assertEqual(len(foo.values), 3) self.assertEqual(foo['a'], 'b') test() self.assertEqual(foo.values, original) def test_patch_dict_with_clear(self): foo = {'initial': object(), 'other': 'something'} original = foo.copy() @patch.dict(foo, clear=True) def test(): self.assertEqual(foo, {}) foo['a'] = 3 foo['other'] = 'something else' test() self.assertEqual(foo, original) @patch.dict(foo, {'a': 'b'}, clear=True) def test(): self.assertEqual(foo, {'a': 'b'}) test() self.assertEqual(foo, original) @patch.dict(foo, [('a', 'b')], clear=True) def test(): self.assertEqual(foo, {'a': 'b'}) test() self.assertEqual(foo, original) def test_patch_dict_with_container_object_and_clear(self): foo = Container() foo['initial'] = object() foo['other'] = 'something' original = foo.values.copy() @patch.dict(foo, clear=True) def test(): self.assertEqual(foo.values, {}) foo['a'] = 3 foo['other'] = 'something else' test() self.assertEqual(foo.values, original) @patch.dict(foo, {'a': 'b'}, clear=True) def test(): self.assertEqual(foo.values, {'a': 'b'}) test() self.assertEqual(foo.values, original) def test_name_preserved(self): foo = {} @patch('%s.SomeClass' % __name__, object()) @patch('%s.SomeClass' % __name__, object(), autospec=True) @patch.object(SomeClass, object()) @patch.dict(foo) def some_name(): pass self.assertEqual(some_name.__name__, 'some_name') def test_patch_with_exception(self): foo = {} @patch.dict(foo, {'a': 'b'}) def test(): raise NameError('Konrad') with self.assertRaises(NameError): test() self.assertEqual(foo, {}) def test_patch_dict_with_string(self): @patch.dict('os.environ', {'konrad_delong': 'some value'}) def test(): self.assertIn('konrad_delong', os.environ) test() def test_patch_dict_with_unicode(self): @patch.dict(u'os.environ', {'konrad_delong': 'some value'}) def test(): self.assertIn('konrad_delong', os.environ) test() def test_patch_dict_decorator_resolution(self): # bpo-35512: Ensure that patch with a string target resolves to # the new dictionary during function call original = support.target.copy() @patch.dict('mock.tests.support.target', {'bar': 'BAR'}) def test(): self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'}) try: support.target = {'foo': 'BAZ'} test() self.assertEqual(support.target, {'foo': 'BAZ'}) finally: support.target = original def test_patch_spec_set(self): @patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True) def test(MockClass): MockClass.z = 'foo' self.assertRaises(AttributeError, test) @patch.object(support, 'SomeClass', spec=SomeClass, spec_set=True) def test(MockClass): MockClass.z = 'foo' self.assertRaises(AttributeError, test) @patch('%s.SomeClass' % __name__, spec_set=True) def test(MockClass): MockClass.z = 'foo' self.assertRaises(AttributeError, test) @patch.object(support, 'SomeClass', spec_set=True) def test(MockClass): MockClass.z = 'foo' self.assertRaises(AttributeError, test) def test_spec_set_inherit(self): @patch('%s.SomeClass' % __name__, spec_set=True) def test(MockClass): instance = MockClass() instance.z = 'foo' self.assertRaises(AttributeError, test) def test_patch_start_stop(self): original = something patcher = patch('%s.something' % __name__) self.assertIs(something, original) mock = patcher.start() try: self.assertIsNot(mock, original) self.assertIs(something, mock) finally: patcher.stop() self.assertIs(something, original) def test_stop_without_start(self): # bpo-36366: calling stop without start will return None. patcher = patch(foo_name, 'bar', 3) self.assertIsNone(patcher.stop()) def test_stop_idempotent(self): # bpo-36366: calling stop on an already stopped patch will return None. patcher = patch(foo_name, 'bar', 3) patcher.start() patcher.stop() self.assertIsNone(patcher.stop()) def test_patchobject_start_stop(self): original = something patcher = patch.object(PTModule, 'something', 'foo') self.assertIs(something, original) replaced = patcher.start() try: self.assertEqual(replaced, 'foo') self.assertIs(something, replaced) finally: patcher.stop() self.assertIs(something, original) def test_patch_dict_start_stop(self): d = {'foo': 'bar'} original = d.copy() patcher = patch.dict(d, [('spam', 'eggs')], clear=True) self.assertEqual(d, original) patcher.start() try: self.assertEqual(d, {'spam': 'eggs'}) finally: patcher.stop() self.assertEqual(d, original) def test_patch_dict_class_decorator(self): this = self d = {'spam': 'eggs'} original = d.copy() class Test(object): def test_first(self): this.assertEqual(d, {'foo': 'bar'}) def test_second(self): this.assertEqual(d, {'foo': 'bar'}) Test = patch.dict(d, {'foo': 'bar'}, clear=True)(Test) self.assertEqual(d, original) test = Test() test.test_first() self.assertEqual(d, original) test.test_second() self.assertEqual(d, original) test = Test() test.test_first() self.assertEqual(d, original) test.test_second() self.assertEqual(d, original) def test_get_only_proxy(self): class Something(object): foo = 'foo' class SomethingElse: foo = 'foo' for thing in Something, SomethingElse, Something(), SomethingElse: proxy = _get_proxy(thing) @patch.object(proxy, 'foo', 'bar') def test(): self.assertEqual(proxy.foo, 'bar') test() self.assertEqual(proxy.foo, 'foo') self.assertEqual(thing.foo, 'foo') self.assertNotIn('foo', proxy.__dict__) def test_get_set_delete_proxy(self): class Something(object): foo = 'foo' class SomethingElse: foo = 'foo' for thing in Something, SomethingElse, Something(), SomethingElse: proxy = _get_proxy(Something, get_only=False) @patch.object(proxy, 'foo', 'bar') def test(): self.assertEqual(proxy.foo, 'bar') test() self.assertEqual(proxy.foo, 'foo') self.assertEqual(thing.foo, 'foo') self.assertNotIn('foo', proxy.__dict__) def test_patch_keyword_args(self): kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33, 'foo': MagicMock()} patcher = patch(foo_name, **kwargs) mock = patcher.start() patcher.stop() self.assertRaises(KeyError, mock) self.assertEqual(mock.foo.bar(), 33) self.assertIsInstance(mock.foo, MagicMock) def test_patch_object_keyword_args(self): kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33, 'foo': MagicMock()} patcher = patch.object(Foo, 'f', **kwargs) mock = patcher.start() patcher.stop() self.assertRaises(KeyError, mock) self.assertEqual(mock.foo.bar(), 33) self.assertIsInstance(mock.foo, MagicMock) def test_patch_dict_keyword_args(self): original = {'foo': 'bar'} copy = original.copy() patcher = patch.dict(original, foo=3, bar=4, baz=5) patcher.start() try: self.assertEqual(original, dict(foo=3, bar=4, baz=5)) finally: patcher.stop() self.assertEqual(original, copy) def test_autospec(self): class Boo(object): def __init__(self, a): pass def f(self, a): pass def g(self): pass foo = 'bar' class Bar(object): def a(self): pass def _test(mock): mock(1) mock.assert_called_with(1) self.assertRaises(TypeError, mock) def _test2(mock): mock.f(1) mock.f.assert_called_with(1) self.assertRaises(TypeError, mock.f) mock.g() mock.g.assert_called_with() self.assertRaises(TypeError, mock.g, 1) self.assertRaises(AttributeError, getattr, mock, 'h') mock.foo.lower() mock.foo.lower.assert_called_with() self.assertRaises(AttributeError, getattr, mock.foo, 'bar') mock.Bar() mock.Bar.assert_called_with() mock.Bar.a() mock.Bar.a.assert_called_with() self.assertRaises(TypeError, mock.Bar.a, 1) mock.Bar().a() mock.Bar().a.assert_called_with() self.assertRaises(TypeError, mock.Bar().a, 1) self.assertRaises(AttributeError, getattr, mock.Bar, 'b') self.assertRaises(AttributeError, getattr, mock.Bar(), 'b') def function(mock): _test(mock) _test2(mock) _test2(mock(1)) self.assertIs(mock, Foo) return mock test = patch(foo_name, autospec=True)(function) mock = test() self.assertIsNot(Foo, mock) # test patching a second time works test() module = sys.modules[__name__] test = patch.object(module, 'Foo', autospec=True)(function) mock = test() self.assertIsNot(Foo, mock) # test patching a second time works test() def test_autospec_function(self): @patch('%s.function' % __name__, autospec=True) def test(mock): function.assert_not_called() self.assertRaises(AssertionError, function.assert_called) self.assertRaises(AssertionError, function.assert_called_once) function(1) self.assertRaises(AssertionError, function.assert_not_called) function.assert_called_with(1) function.assert_called() function.assert_called_once() function(2, 3) function.assert_called_with(2, 3) self.assertRaises(TypeError, function) self.assertRaises(AttributeError, getattr, function, 'foo') test() def test_autospec_keywords(self): @patch('%s.function' % __name__, autospec=True, return_value=3) def test(mock_function): #self.assertEqual(function.abc, 'foo') return function(1, 2) result = test() self.assertEqual(result, 3) def test_autospec_staticmethod(self): with patch('%s.Foo.static_method' % __name__, autospec=True) as method: Foo.static_method() method.assert_called_once_with() def test_autospec_classmethod(self): with patch('%s.Foo.class_method' % __name__, autospec=True) as method: Foo.class_method() method.assert_called_once_with() def test_autospec_with_new(self): patcher = patch('%s.function' % __name__, new=3, autospec=True) self.assertRaises(TypeError, patcher.start) module = sys.modules[__name__] patcher = patch.object(module, 'function', new=3, autospec=True) self.assertRaises(TypeError, patcher.start) def test_autospec_with_object(self): class Bar(Foo): extra = [] patcher = patch(foo_name, autospec=Bar) mock = patcher.start() try: self.assertIsInstance(mock, Bar) self.assertIsInstance(mock.extra, list) finally: patcher.stop() def test_autospec_inherits(self): FooClass = Foo patcher = patch(foo_name, autospec=True) mock = patcher.start() try: self.assertIsInstance(mock, FooClass) self.assertIsInstance(mock(3), FooClass) finally: patcher.stop() def test_autospec_name(self): patcher = patch(foo_name, autospec=True) mock = patcher.start() try: self.assertIn(" name='Foo'", repr(mock)) self.assertIn(" name='Foo.f'", repr(mock.f)) self.assertIn(" name='Foo()'", repr(mock(None))) self.assertIn(" name='Foo().f'", repr(mock(None).f)) finally: patcher.stop() def test_tracebacks(self): @patch.object(Foo, 'f', object()) def test(): raise AssertionError try: test() except: err = sys.exc_info() result = unittest.TextTestResult(None, None, 0) traceback = result._exc_info_to_string(err, self) self.assertIn('raise AssertionError', traceback) def test_new_callable_patch(self): patcher = patch(foo_name, new_callable=NonCallableMagicMock) m1 = patcher.start() patcher.stop() m2 = patcher.start() patcher.stop() self.assertIsNot(m1, m2) for mock in m1, m2: self.assertNotCallable(m1) def test_new_callable_patch_object(self): patcher = patch.object(Foo, 'f', new_callable=NonCallableMagicMock) m1 = patcher.start() patcher.stop() m2 = patcher.start() patcher.stop() self.assertIsNot(m1, m2) for mock in m1, m2: self.assertNotCallable(m1) def test_new_callable_keyword_arguments(self): class Bar(object): kwargs = None def __init__(self, **kwargs): Bar.kwargs = kwargs patcher = patch(foo_name, new_callable=Bar, arg1=1, arg2=2) m = patcher.start() try: self.assertIs(type(m), Bar) self.assertEqual(Bar.kwargs, dict(arg1=1, arg2=2)) finally: patcher.stop() def test_new_callable_spec(self): class Bar(object): kwargs = None def __init__(self, **kwargs): Bar.kwargs = kwargs patcher = patch(foo_name, new_callable=Bar, spec=Bar) patcher.start() try: self.assertEqual(Bar.kwargs, dict(spec=Bar)) finally: patcher.stop() patcher = patch(foo_name, new_callable=Bar, spec_set=Bar) patcher.start() try: self.assertEqual(Bar.kwargs, dict(spec_set=Bar)) finally: patcher.stop() def test_new_callable_create(self): non_existent_attr = '%s.weeeee' % foo_name p = patch(non_existent_attr, new_callable=NonCallableMock) self.assertRaises(AttributeError, p.start) p = patch(non_existent_attr, new_callable=NonCallableMock, create=True) m = p.start() try: self.assertNotCallable(m, magic=False) finally: p.stop() def test_new_callable_incompatible_with_new(self): self.assertRaises( ValueError, patch, foo_name, new=object(), new_callable=MagicMock ) self.assertRaises( ValueError, patch.object, Foo, 'f', new=object(), new_callable=MagicMock ) def test_new_callable_incompatible_with_autospec(self): self.assertRaises( ValueError, patch, foo_name, new_callable=MagicMock, autospec=True ) self.assertRaises( ValueError, patch.object, Foo, 'f', new_callable=MagicMock, autospec=True ) def test_new_callable_inherit_for_mocks(self): class MockSub(Mock): pass MockClasses = ( NonCallableMock, NonCallableMagicMock, MagicMock, Mock, MockSub ) for Klass in MockClasses: for arg in 'spec', 'spec_set': kwargs = {arg: True} p = patch(foo_name, new_callable=Klass, **kwargs) m = p.start() try: instance = m.return_value self.assertRaises(AttributeError, getattr, instance, 'x') finally: p.stop() def test_new_callable_inherit_non_mock(self): class NotAMock(object): def __init__(self, spec): self.spec = spec p = patch(foo_name, new_callable=NotAMock, spec=True) m = p.start() try: self.assertTrue(is_instance(m, NotAMock)) self.assertRaises(AttributeError, getattr, m, 'return_value') finally: p.stop() self.assertEqual(m.spec, Foo) def test_new_callable_class_decorating(self): test = self original = Foo class SomeTest(object): def _test(self, mock_foo): test.assertIsNot(Foo, original) test.assertIs(Foo, mock_foo) test.assertIsInstance(Foo, SomeClass) def test_two(self, mock_foo): self._test(mock_foo) def test_one(self, mock_foo): self._test(mock_foo) SomeTest = patch(foo_name, new_callable=SomeClass)(SomeTest) SomeTest().test_one() SomeTest().test_two() self.assertIs(Foo, original) def test_patch_multiple(self): original_foo = Foo original_f = Foo.f original_g = Foo.g patcher1 = patch.multiple(foo_name, f=1, g=2) patcher2 = patch.multiple(Foo, f=1, g=2) for patcher in patcher1, patcher2: patcher.start() try: self.assertIs(Foo, original_foo) self.assertEqual(Foo.f, 1) self.assertEqual(Foo.g, 2) finally: patcher.stop() self.assertIs(Foo, original_foo) self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) @patch.multiple(foo_name, f=3, g=4) def test(): self.assertIs(Foo, original_foo) self.assertEqual(Foo.f, 3) self.assertEqual(Foo.g, 4) test() def test_patch_multiple_no_kwargs(self): self.assertRaises(ValueError, patch.multiple, foo_name) self.assertRaises(ValueError, patch.multiple, Foo) def test_patch_multiple_create_mocks(self): original_foo = Foo original_f = Foo.f original_g = Foo.g @patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT) def test(f, foo): self.assertIs(Foo, original_foo) self.assertIs(Foo.f, f) self.assertEqual(Foo.g, 3) self.assertIs(Foo.foo, foo) self.assertTrue(is_instance(f, MagicMock)) self.assertTrue(is_instance(foo, MagicMock)) test() self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_patch_multiple_create_mocks_different_order(self): original_f = Foo.f original_g = Foo.g patcher = patch.object(Foo, 'f', 3) patcher.attribute_name = 'f' other = patch.object(Foo, 'g', DEFAULT) other.attribute_name = 'g' patcher.additional_patchers = [other] @patcher def test(g): self.assertIs(Foo.g, g) self.assertEqual(Foo.f, 3) test() self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_patch_multiple_stacked_decorators(self): original_foo = Foo original_f = Foo.f original_g = Foo.g @patch.multiple(foo_name, f=DEFAULT) @patch.multiple(foo_name, foo=DEFAULT) @patch(foo_name + '.g') def test1(g, **kwargs): _test(g, **kwargs) @patch.multiple(foo_name, f=DEFAULT) @patch(foo_name + '.g') @patch.multiple(foo_name, foo=DEFAULT) def test2(g, **kwargs): _test(g, **kwargs) @patch(foo_name + '.g') @patch.multiple(foo_name, f=DEFAULT) @patch.multiple(foo_name, foo=DEFAULT) def test3(g, **kwargs): _test(g, **kwargs) def _test(g, **kwargs): f = kwargs.pop('f') foo = kwargs.pop('foo') self.assertFalse(kwargs) self.assertIs(Foo, original_foo) self.assertIs(Foo.f, f) self.assertIs(Foo.g, g) self.assertIs(Foo.foo, foo) self.assertTrue(is_instance(f, MagicMock)) self.assertTrue(is_instance(g, MagicMock)) self.assertTrue(is_instance(foo, MagicMock)) test1() test2() test3() self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_patch_multiple_create_mocks_patcher(self): original_foo = Foo original_f = Foo.f original_g = Foo.g patcher = patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT) result = patcher.start() try: f = result['f'] foo = result['foo'] self.assertEqual(set(result), {'f', 'foo'}) self.assertIs(Foo, original_foo) self.assertIs(Foo.f, f) self.assertIs(Foo.foo, foo) self.assertTrue(is_instance(f, MagicMock)) self.assertTrue(is_instance(foo, MagicMock)) finally: patcher.stop() self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_patch_multiple_decorating_class(self): test = self original_foo = Foo original_f = Foo.f original_g = Foo.g class SomeTest(object): def _test(self, f, foo): test.assertIs(Foo, original_foo) test.assertIs(Foo.f, f) test.assertEqual(Foo.g, 3) test.assertIs(Foo.foo, foo) test.assertTrue(is_instance(f, MagicMock)) test.assertTrue(is_instance(foo, MagicMock)) def test_two(self, f, foo): self._test(f, foo) def test_one(self, f, foo): self._test(f, foo) SomeTest = patch.multiple( foo_name, f=DEFAULT, g=3, foo=DEFAULT )(SomeTest) thing = SomeTest() thing.test_one() thing.test_two() self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_patch_multiple_create(self): patcher = patch.multiple(Foo, blam='blam') self.assertRaises(AttributeError, patcher.start) patcher = patch.multiple(Foo, blam='blam', create=True) patcher.start() try: self.assertEqual(Foo.blam, 'blam') finally: patcher.stop() self.assertFalse(hasattr(Foo, 'blam')) def test_patch_multiple_spec_set(self): # if spec_set works then we can assume that spec and autospec also # work as the underlying machinery is the same patcher = patch.multiple(Foo, foo=DEFAULT, spec_set=['a', 'b']) result = patcher.start() try: self.assertEqual(Foo.foo, result['foo']) Foo.foo.a(1) Foo.foo.b(2) Foo.foo.a.assert_called_with(1) Foo.foo.b.assert_called_with(2) self.assertRaises(AttributeError, setattr, Foo.foo, 'c', None) finally: patcher.stop() def test_patch_multiple_new_callable(self): class Thing(object): pass patcher = patch.multiple( Foo, f=DEFAULT, g=DEFAULT, new_callable=Thing ) result = patcher.start() try: self.assertIs(Foo.f, result['f']) self.assertIs(Foo.g, result['g']) self.assertIsInstance(Foo.f, Thing) self.assertIsInstance(Foo.g, Thing) self.assertIsNot(Foo.f, Foo.g) finally: patcher.stop() def test_nested_patch_failure(self): original_f = Foo.f original_g = Foo.g @patch.object(Foo, 'g', 1) @patch.object(Foo, 'missing', 1) @patch.object(Foo, 'f', 1) def thing1(): pass @patch.object(Foo, 'missing', 1) @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) def thing2(): pass @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) @patch.object(Foo, 'missing', 1) def thing3(): pass for func in thing1, thing2, thing3: self.assertRaises(AttributeError, func) self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_new_callable_failure(self): original_f = Foo.f original_g = Foo.g original_foo = Foo.foo def crasher(): raise NameError('crasher') @patch.object(Foo, 'g', 1) @patch.object(Foo, 'foo', new_callable=crasher) @patch.object(Foo, 'f', 1) def thing1(): pass @patch.object(Foo, 'foo', new_callable=crasher) @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) def thing2(): pass @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) @patch.object(Foo, 'foo', new_callable=crasher) def thing3(): pass for func in thing1, thing2, thing3: self.assertRaises(NameError, func) self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) self.assertEqual(Foo.foo, original_foo) def test_patch_multiple_failure(self): original_f = Foo.f original_g = Foo.g patcher = patch.object(Foo, 'f', 1) patcher.attribute_name = 'f' good = patch.object(Foo, 'g', 1) good.attribute_name = 'g' bad = patch.object(Foo, 'missing', 1) bad.attribute_name = 'missing' for additionals in [good, bad], [bad, good]: patcher.additional_patchers = additionals @patcher def func(): pass self.assertRaises(AttributeError, func) self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) def test_patch_multiple_new_callable_failure(self): original_f = Foo.f original_g = Foo.g original_foo = Foo.foo def crasher(): raise NameError('crasher') patcher = patch.object(Foo, 'f', 1) patcher.attribute_name = 'f' good = patch.object(Foo, 'g', 1) good.attribute_name = 'g' bad = patch.object(Foo, 'foo', new_callable=crasher) bad.attribute_name = 'foo' for additionals in [good, bad], [bad, good]: patcher.additional_patchers = additionals @patcher def func(): pass self.assertRaises(NameError, func) self.assertEqual(Foo.f, original_f) self.assertEqual(Foo.g, original_g) self.assertEqual(Foo.foo, original_foo) def test_patch_multiple_string_subclasses(self): for base in (str, unicode): Foo = type('Foo', (base,), {'fish': 'tasty'}) foo = Foo() @patch.multiple(foo, fish='nearly gone') def test(): self.assertEqual(foo.fish, 'nearly gone') test() self.assertEqual(foo.fish, 'tasty') @patch('mock.patch.TEST_PREFIX', 'foo') def test_patch_test_prefix(self): class Foo(object): thing = 'original' def foo_one(self): return self.thing def foo_two(self): return self.thing def test_one(self): return self.thing def test_two(self): return self.thing Foo = patch.object(Foo, 'thing', 'changed')(Foo) foo = Foo() self.assertEqual(foo.foo_one(), 'changed') self.assertEqual(foo.foo_two(), 'changed') self.assertEqual(foo.test_one(), 'original') self.assertEqual(foo.test_two(), 'original') @patch('mock.patch.TEST_PREFIX', 'bar') def test_patch_dict_test_prefix(self): class Foo(object): def bar_one(self): return dict(the_dict) def bar_two(self): return dict(the_dict) def test_one(self): return dict(the_dict) def test_two(self): return dict(the_dict) the_dict = {'key': 'original'} Foo = patch.dict(the_dict, key='changed')(Foo) foo =Foo() self.assertEqual(foo.bar_one(), {'key': 'changed'}) self.assertEqual(foo.bar_two(), {'key': 'changed'}) self.assertEqual(foo.test_one(), {'key': 'original'}) self.assertEqual(foo.test_two(), {'key': 'original'}) def test_patch_with_spec_mock_repr(self): for arg in ('spec', 'autospec', 'spec_set'): p = patch('%s.SomeClass' % __name__, **{arg: True}) m = p.start() try: self.assertIn(" name='SomeClass'", repr(m)) self.assertIn(" name='SomeClass.class_attribute'", repr(m.class_attribute)) self.assertIn(" name='SomeClass()'", repr(m())) self.assertIn(" name='SomeClass().class_attribute'", repr(m().class_attribute)) finally: p.stop() def test_patch_nested_autospec_repr(self): p = patch('mock.tests.support', autospec=True) m = p.start() try: self.assertIn(" name='support.SomeClass.wibble()'", repr(m.SomeClass.wibble())) self.assertIn(" name='support.SomeClass().wibble()'", repr(m.SomeClass().wibble())) finally: p.stop() def test_mock_calls_with_patch(self): for arg in ('spec', 'autospec', 'spec_set'): p = patch('%s.SomeClass' % __name__, **{arg: True}) m = p.start() try: m.wibble() kalls = [call.wibble()] self.assertEqual(m.mock_calls, kalls) self.assertEqual(m.method_calls, kalls) self.assertEqual(m.wibble.mock_calls, [call()]) result = m() kalls.append(call()) self.assertEqual(m.mock_calls, kalls) result.wibble() kalls.append(call().wibble()) self.assertEqual(m.mock_calls, kalls) self.assertEqual(result.mock_calls, [call.wibble()]) self.assertEqual(result.wibble.mock_calls, [call()]) self.assertEqual(result.method_calls, [call.wibble()]) finally: p.stop() def test_patch_imports_lazily(self): p1 = patch('squizz.squozz') self.assertRaises(ImportError, p1.start) with uncache('squizz'): squizz = Mock() sys.modules['squizz'] = squizz squizz.squozz = 6 p1 = patch('squizz.squozz') squizz.squozz = 3 p1.start() p1.stop() self.assertEqual(squizz.squozz, 3) def test_patch_propogrates_exc_on_exit(self): class holder: exc_info = None, None, None class custom_patch(_patch): def __exit__(self, etype=None, val=None, tb=None): _patch.__exit__(self, etype, val, tb) holder.exc_info = etype, val, tb stop = __exit__ def with_custom_patch(target): getter, attribute = _get_target(target) return custom_patch( getter, attribute, DEFAULT, None, False, None, None, None, {} ) @with_custom_patch('squizz.squozz') def test(mock): raise RuntimeError with uncache('squizz'): squizz = Mock() sys.modules['squizz'] = squizz self.assertRaises(RuntimeError, test) self.assertIs(holder.exc_info[0], RuntimeError) self.assertIsNotNone(holder.exc_info[1], 'exception value not propgated') self.assertIsNotNone(holder.exc_info[2], 'exception traceback not propgated') def test_create_and_specs(self): for kwarg in ('spec', 'spec_set', 'autospec'): p = patch('%s.doesnotexist' % __name__, create=True, **{kwarg: True}) self.assertRaises(TypeError, p.start) self.assertRaises(NameError, lambda: doesnotexist) # check that spec with create is innocuous if the original exists p = patch(MODNAME, create=True, **{kwarg: True}) p.start() p.stop() def test_multiple_specs(self): original = PTModule for kwarg in ('spec', 'spec_set'): p = patch(MODNAME, autospec=0, **{kwarg: 0}) self.assertRaises(TypeError, p.start) self.assertIs(PTModule, original) for kwarg in ('spec', 'autospec'): p = patch(MODNAME, spec_set=0, **{kwarg: 0}) self.assertRaises(TypeError, p.start) self.assertIs(PTModule, original) for kwarg in ('spec_set', 'autospec'): p = patch(MODNAME, spec=0, **{kwarg: 0}) self.assertRaises(TypeError, p.start) self.assertIs(PTModule, original) def test_specs_false_instead_of_none(self): p = patch(MODNAME, spec=False, spec_set=False, autospec=False) mock = p.start() try: # no spec should have been set, so attribute access should not fail mock.does_not_exist mock.does_not_exist = 3 finally: p.stop() def test_falsey_spec(self): for kwarg in ('spec', 'autospec', 'spec_set'): p = patch(MODNAME, **{kwarg: 0}) m = p.start() try: self.assertRaises(AttributeError, getattr, m, 'doesnotexit') finally: p.stop() def test_spec_set_true(self): for kwarg in ('spec', 'autospec'): p = patch(MODNAME, spec_set=True, **{kwarg: True}) m = p.start() try: self.assertRaises(AttributeError, setattr, m, 'doesnotexist', 'something') self.assertRaises(AttributeError, getattr, m, 'doesnotexist') finally: p.stop() def test_callable_spec_as_list(self): spec = ('__call__',) p = patch(MODNAME, spec=spec) m = p.start() try: self.assertTrue(callable(m)) finally: p.stop() def test_not_callable_spec_as_list(self): spec = ('foo', 'bar') p = patch(MODNAME, spec=spec) m = p.start() try: self.assertFalse(callable(m)) finally: p.stop() def test_patch_stopall(self): unlink = os.unlink chdir = os.chdir path = os.path patch('os.unlink', something).start() patch('os.chdir', something_else).start() @patch('os.path') def patched(mock_path): patch.stopall() self.assertIs(os.path, mock_path) self.assertIs(os.unlink, unlink) self.assertIs(os.chdir, chdir) patched() self.assertIs(os.path, path) def test_wrapped_patch(self): decorated = patch('sys.modules')(function) self.assertIs(decorated.__wrapped__, function) def test_wrapped_several_times_patch(self): decorated = patch('sys.modules')(function) decorated = patch('sys.modules')(decorated) self.assertIs(decorated.__wrapped__, function) def test_wrapped_patch_object(self): decorated = patch.object(sys, 'modules')(function) self.assertIs(decorated.__wrapped__, function) def test_wrapped_patch_dict(self): decorated = patch.dict('sys.modules')(function) self.assertIs(decorated.__wrapped__, function) def test_wrapped_patch_multiple(self): decorated = patch.multiple('sys', modules={})(function) self.assertIs(decorated.__wrapped__, function) def test_stopall_lifo(self): stopped = [] class thing(object): one = two = three = None def get_patch(attribute): class mypatch(_patch): def stop(self): stopped.append(attribute) return super(mypatch, self).stop() return mypatch(lambda: thing, attribute, None, None, False, None, None, None, {}) [get_patch(val).start() for val in ("one", "two", "three")] patch.stopall() self.assertEqual(stopped, ["three", "two", "one"]) def test_special_attrs(self): def foo(x=0): """TEST""" return x with patch.object(foo, '__defaults__', (1, )): self.assertEqual(foo(), 1) self.assertEqual(foo(), 0) with patch.object(foo, '__doc__', "FUN"): self.assertEqual(foo.__doc__, "FUN") self.assertEqual(foo.__doc__, "TEST") with patch.object(foo, '__module__', "testpatch2"): self.assertEqual(foo.__module__, "testpatch2") self.assertEqual(foo.__module__, __name__) if hasattr(self.test_special_attrs, '__annotations__'): with patch.object(foo, '__annotations__', dict([('s', 1, )])): self.assertEqual(foo.__annotations__, dict([('s', 1, )])) self.assertEqual(foo.__annotations__, dict()) if hasattr(self.test_special_attrs, '__kwdefaults__'): foo = eval("lambda *a, x=0: x") with patch.object(foo, '__kwdefaults__', dict([('x', 1, )])): self.assertEqual(foo(), 1) self.assertEqual(foo(), 0) def test_dotted_but_module_not_loaded(self): # This exercises the AttributeError branch of _dot_lookup. # make sure it's there import mock.tests.support # now make sure it's not: with patch.dict('sys.modules'): del sys.modules['mock.tests.support'] del sys.modules['mock.tests'] del sys.modules['mock.mock'] del sys.modules['mock'] # now make sure we can patch based on a dotted path: @patch('mock.tests.support.X') def test(mock): pass test() def test_invalid_target(self): with self.assertRaises(TypeError): patch('') def test_cant_set_kwargs_when_passing_a_mock(self): @patch('mock.tests.support.X', new=object(), x=1) def test(): pass with self.assertRaises(TypeError): test() if __name__ == '__main__': unittest.main() mock-3.0.5/mock/tests/testsealable.py000066400000000000000000000115651346437275100176110ustar00rootroot00000000000000import unittest import mock class SampleObject: def method_sample1(self): pass def method_sample2(self): pass class TestSealable(unittest.TestCase): def test_attributes_return_more_mocks_by_default(self): m = mock.Mock() self.assertIsInstance(m.test, mock.Mock) self.assertIsInstance(m.test(), mock.Mock) self.assertIsInstance(m.test().test2(), mock.Mock) def test_new_attributes_cannot_be_accessed_on_seal(self): m = mock.Mock() mock.seal(m) with self.assertRaises(AttributeError): m.test with self.assertRaises(AttributeError): m() def test_new_attributes_cannot_be_set_on_seal(self): m = mock.Mock() mock.seal(m) with self.assertRaises(AttributeError): m.test = 1 def test_existing_attributes_can_be_set_on_seal(self): m = mock.Mock() m.test.test2 = 1 mock.seal(m) m.test.test2 = 2 self.assertEqual(m.test.test2, 2) def test_new_attributes_cannot_be_set_on_child_of_seal(self): m = mock.Mock() m.test.test2 = 1 mock.seal(m) with self.assertRaises(AttributeError): m.test.test3 = 1 def test_existing_attributes_allowed_after_seal(self): m = mock.Mock() m.test.return_value = 3 mock.seal(m) self.assertEqual(m.test(), 3) def test_initialized_attributes_allowed_after_seal(self): m = mock.Mock(test_value=1) mock.seal(m) self.assertEqual(m.test_value, 1) def test_call_on_sealed_mock_fails(self): m = mock.Mock() mock.seal(m) with self.assertRaises(AttributeError): m() def test_call_on_defined_sealed_mock_succeeds(self): m = mock.Mock(return_value=5) mock.seal(m) self.assertEqual(m(), 5) def test_seals_recurse_on_added_attributes(self): m = mock.Mock() m.test1.test2().test3 = 4 mock.seal(m) self.assertEqual(m.test1.test2().test3, 4) with self.assertRaises(AttributeError): m.test1.test2().test4 with self.assertRaises(AttributeError): m.test1.test3 def test_seals_recurse_on_magic_methods(self): m = mock.MagicMock() m.test1.test2["a"].test3 = 4 m.test1.test3[2:5].test3 = 4 mock.seal(m) self.assertEqual(m.test1.test2["a"].test3, 4) self.assertEqual(m.test1.test2[2:5].test3, 4) with self.assertRaises(AttributeError): m.test1.test2["a"].test4 with self.assertRaises(AttributeError): m.test1.test3[2:5].test4 def test_seals_dont_recurse_on_manual_attributes(self): m = mock.Mock(name="root_mock") m.test1.test2 = mock.Mock(name="not_sealed") m.test1.test2.test3 = 4 mock.seal(m) self.assertEqual(m.test1.test2.test3, 4) m.test1.test2.test4 # Does not raise m.test1.test2.test4 = 1 # Does not raise def test_integration_with_spec_att_definition(self): """You are not restricted when using mock with spec""" m = mock.Mock(SampleObject) m.attr_sample1 = 1 m.attr_sample3 = 3 mock.seal(m) self.assertEqual(m.attr_sample1, 1) self.assertEqual(m.attr_sample3, 3) with self.assertRaises(AttributeError): m.attr_sample2 def test_integration_with_spec_method_definition(self): """You need to defin the methods, even if they are in the spec""" m = mock.Mock(SampleObject) m.method_sample1.return_value = 1 mock.seal(m) self.assertEqual(m.method_sample1(), 1) with self.assertRaises(AttributeError): m.method_sample2() def test_integration_with_spec_method_definition_respects_spec(self): """You cannot define methods out of the spec""" m = mock.Mock(SampleObject) with self.assertRaises(AttributeError): m.method_sample3.return_value = 3 def test_sealed_exception_has_attribute_name(self): m = mock.Mock() mock.seal(m) with self.assertRaises(AttributeError) as cm: m.SECRETE_name self.assertIn("SECRETE_name", str(cm.exception)) def test_attribute_chain_is_maintained(self): m = mock.Mock(name="mock_name") m.test1.test2.test3.test4 mock.seal(m) with self.assertRaises(AttributeError) as cm: m.test1.test2.test3.test4.boom self.assertIn("mock_name.test1.test2.test3.test4.boom", str(cm.exception)) def test_call_chain_is_maintained(self): m = mock.Mock() m.test1().test2.test3().test4 mock.seal(m) with self.assertRaises(AttributeError) as cm: m.test1().test2.test3().test4() self.assertIn("mock.test1().test2.test3().test4", str(cm.exception)) if __name__ == "__main__": unittest.main() mock-3.0.5/mock/tests/testsentinel.py000066400000000000000000000026101346437275100176510ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ import unittest import copy import pickle from mock import sentinel, DEFAULT class SentinelTest(unittest.TestCase): def testSentinels(self): self.assertEqual(sentinel.whatever, sentinel.whatever, 'sentinel not stored') self.assertNotEqual(sentinel.whatever, sentinel.whateverelse, 'sentinel should be unique') def testSentinelName(self): self.assertEqual(str(sentinel.whatever), 'sentinel.whatever', 'sentinel name incorrect') def testDEFAULT(self): self.assertIs(DEFAULT, sentinel.DEFAULT) def testBases(self): # If this doesn't raise an AttributeError then help(mock) is broken self.assertRaises(AttributeError, lambda: sentinel.__bases__) def testPickle(self): for proto in range(pickle.HIGHEST_PROTOCOL+1): pickled = pickle.dumps(sentinel.whatever, proto) unpickled = pickle.loads(pickled) self.assertIs(unpickled, sentinel.whatever) def testCopy(self): self.assertIs(copy.copy(sentinel.whatever), sentinel.whatever) self.assertIs(copy.deepcopy(sentinel.whatever), sentinel.whatever) if __name__ == '__main__': unittest.main() mock-3.0.5/mock/tests/testsupport.py000066400000000000000000000005611346437275100175470ustar00rootroot00000000000000# Tests to make sure helpers we backport are actually working! from unittest import TestCase from .support import uncache class TestUncache(TestCase): def test_cant_uncache_sys(self): with self.assertRaises(ValueError): with uncache('sys'): pass def test_uncache_non_existent(self): with uncache('mock.tests.support.bad'): pass mock-3.0.5/mock/tests/testwith.py000066400000000000000000000270221346437275100170070ustar00rootroot00000000000000# Copyright (C) 2007-2012 Michael Foord & the mock team # E-mail: fuzzyman AT voidspace DOT org DOT uk # http://www.voidspace.org.uk/python/mock/ from warnings import catch_warnings import unittest from mock.tests.support import is_instance from mock import MagicMock, Mock, patch, sentinel, mock_open, call something = sentinel.Something something_else = sentinel.SomethingElse class SampleException(Exception): pass class WithTest(unittest.TestCase): def test_with_statement(self): with patch('%s.something' % __name__, sentinel.Something2): self.assertEqual(something, sentinel.Something2, "unpatched") self.assertEqual(something, sentinel.Something) def test_with_statement_exception(self): with self.assertRaises(SampleException): with patch('%s.something' % __name__, sentinel.Something2): self.assertEqual(something, sentinel.Something2, "unpatched") raise SampleException() self.assertEqual(something, sentinel.Something) def test_with_statement_as(self): with patch('%s.something' % __name__) as mock_something: self.assertEqual(something, mock_something, "unpatched") self.assertTrue(is_instance(mock_something, MagicMock), "patching wrong type") self.assertEqual(something, sentinel.Something) def test_patch_object_with_statement(self): class Foo(object): something = 'foo' original = Foo.something with patch.object(Foo, 'something'): self.assertNotEqual(Foo.something, original, "unpatched") self.assertEqual(Foo.something, original) def test_with_statement_nested(self): with catch_warnings(record=True): with patch('%s.something' % __name__) as mock_something: with patch('%s.something_else' % __name__) as mock_something_else: self.assertEqual(something, mock_something, "unpatched") self.assertEqual(something_else, mock_something_else, "unpatched") self.assertEqual(something, sentinel.Something) self.assertEqual(something_else, sentinel.SomethingElse) def test_with_statement_specified(self): with patch('%s.something' % __name__, sentinel.Patched) as mock_something: self.assertEqual(something, mock_something, "unpatched") self.assertEqual(mock_something, sentinel.Patched, "wrong patch") self.assertEqual(something, sentinel.Something) def testContextManagerMocking(self): mock = Mock() mock.__enter__ = Mock() mock.__exit__ = Mock() mock.__exit__.return_value = False with mock as m: self.assertEqual(m, mock.__enter__.return_value) mock.__enter__.assert_called_with() mock.__exit__.assert_called_with(None, None, None) def test_context_manager_with_magic_mock(self): mock = MagicMock() with self.assertRaises(TypeError): with mock: 'foo' + 3 mock.__enter__.assert_called_with() self.assertTrue(mock.__exit__.called) def test_with_statement_same_attribute(self): with patch('%s.something' % __name__, sentinel.Patched) as mock_something: self.assertEqual(something, mock_something, "unpatched") with patch('%s.something' % __name__) as mock_again: self.assertEqual(something, mock_again, "unpatched") self.assertEqual(something, mock_something, "restored with wrong instance") self.assertEqual(something, sentinel.Something, "not restored") def test_with_statement_imbricated(self): with patch('%s.something' % __name__) as mock_something: self.assertEqual(something, mock_something, "unpatched") with patch('%s.something_else' % __name__) as mock_something_else: self.assertEqual(something_else, mock_something_else, "unpatched") self.assertEqual(something, sentinel.Something) self.assertEqual(something_else, sentinel.SomethingElse) def test_dict_context_manager(self): foo = {} with patch.dict(foo, {'a': 'b'}): self.assertEqual(foo, {'a': 'b'}) self.assertEqual(foo, {}) with self.assertRaises(NameError): with patch.dict(foo, {'a': 'b'}): self.assertEqual(foo, {'a': 'b'}) raise NameError('Konrad') self.assertEqual(foo, {}) def test_double_patch_instance_method(self): class C: def f(self): pass c = C() with patch.object(c, 'f', autospec=True) as patch1: with patch.object(c, 'f', autospec=True) as patch2: c.f() self.assertEqual(patch2.call_count, 1) self.assertEqual(patch1.call_count, 0) c.f() self.assertEqual(patch1.call_count, 1) class TestMockOpen(unittest.TestCase): def test_mock_open(self): mock = mock_open() with patch('%s.open' % __name__, mock, create=True) as patched: self.assertIs(patched, mock) open('foo') mock.assert_called_once_with('foo') def test_mock_open_context_manager(self): mock = mock_open() handle = mock.return_value with patch('%s.open' % __name__, mock, create=True): with open('foo') as f: f.read() expected_calls = [call('foo'), call().__enter__(), call().read(), call().__exit__(None, None, None)] self.assertEqual(mock.mock_calls, expected_calls) self.assertIs(f, handle) def test_mock_open_context_manager_multiple_times(self): mock = mock_open() with patch('%s.open' % __name__, mock, create=True): with open('foo') as f: f.read() with open('bar') as f: f.read() expected_calls = [ call('foo'), call().__enter__(), call().read(), call().__exit__(None, None, None), call('bar'), call().__enter__(), call().read(), call().__exit__(None, None, None)] self.assertEqual(mock.mock_calls, expected_calls) def test_explicit_mock(self): mock = MagicMock() mock_open(mock) with patch('%s.open' % __name__, mock, create=True) as patched: self.assertIs(patched, mock) open('foo') mock.assert_called_once_with('foo') def test_read_data(self): mock = mock_open(read_data='foo') with patch('%s.open' % __name__, mock, create=True): h = open('bar') result = h.read() self.assertEqual(result, 'foo') def test_readline_data(self): # Check that readline will return all the lines from the fake file # And that once fully consumed, readline will return an empty string. mock = mock_open(read_data='foo\nbar\nbaz\n') with patch('%s.open' % __name__, mock, create=True): h = open('bar') line1 = h.readline() line2 = h.readline() line3 = h.readline() self.assertEqual(line1, 'foo\n') self.assertEqual(line2, 'bar\n') self.assertEqual(line3, 'baz\n') self.assertEqual(h.readline(), '') # Check that we properly emulate a file that doesn't end in a newline mock = mock_open(read_data='foo') with patch('%s.open' % __name__, mock, create=True): h = open('bar') result = h.readline() self.assertEqual(result, 'foo') self.assertEqual(h.readline(), '') def test_dunder_iter_data(self): # Check that dunder_iter will return all the lines from the fake file. mock = mock_open(read_data='foo\nbar\nbaz\n') with patch('%s.open' % __name__, mock, create=True): h = open('bar') lines = [l for l in h] self.assertEqual(lines[0], 'foo\n') self.assertEqual(lines[1], 'bar\n') self.assertEqual(lines[2], 'baz\n') self.assertEqual(h.readline(), '') def test_readlines_data(self): # Test that emulating a file that ends in a newline character works mock = mock_open(read_data='foo\nbar\nbaz\n') with patch('%s.open' % __name__, mock, create=True): h = open('bar') result = h.readlines() self.assertEqual(result, ['foo\n', 'bar\n', 'baz\n']) # Test that files without a final newline will also be correctly # emulated mock = mock_open(read_data='foo\nbar\nbaz') with patch('%s.open' % __name__, mock, create=True): h = open('bar') result = h.readlines() self.assertEqual(result, ['foo\n', 'bar\n', 'baz']) def test_read_bytes(self): mock = mock_open(read_data=b'\xc6') with patch('%s.open' % __name__, mock, create=True): with open('abc', 'rb') as f: result = f.read() self.assertEqual(result, b'\xc6') def test_readline_bytes(self): m = mock_open(read_data=b'abc\ndef\nghi\n') with patch('%s.open' % __name__, m, create=True): with open('abc', 'rb') as f: line1 = f.readline() line2 = f.readline() line3 = f.readline() self.assertEqual(line1, b'abc\n') self.assertEqual(line2, b'def\n') self.assertEqual(line3, b'ghi\n') def test_readlines_bytes(self): m = mock_open(read_data=b'abc\ndef\nghi\n') with patch('%s.open' % __name__, m, create=True): with open('abc', 'rb') as f: result = f.readlines() self.assertEqual(result, [b'abc\n', b'def\n', b'ghi\n']) def test_mock_open_read_with_argument(self): # At one point calling read with an argument was broken # for mocks returned by mock_open some_data = 'foo\nbar\nbaz' mock = mock_open(read_data=some_data) self.assertEqual(mock().read(10), some_data[:10]) self.assertEqual(mock().read(10), some_data[:10]) f = mock() self.assertEqual(f.read(10), some_data[:10]) self.assertEqual(f.read(10), some_data[10:]) def test_interleaved_reads(self): # Test that calling read, readline, and readlines pulls data # sequentially from the data we preload with mock = mock_open(read_data='foo\nbar\nbaz\n') with patch('%s.open' % __name__, mock, create=True): h = open('bar') line1 = h.readline() rest = h.readlines() self.assertEqual(line1, 'foo\n') self.assertEqual(rest, ['bar\n', 'baz\n']) mock = mock_open(read_data='foo\nbar\nbaz\n') with patch('%s.open' % __name__, mock, create=True): h = open('bar') line1 = h.readline() rest = h.read() self.assertEqual(line1, 'foo\n') self.assertEqual(rest, 'bar\nbaz\n') def test_overriding_return_values(self): mock = mock_open(read_data='foo') handle = mock() handle.read.return_value = 'bar' handle.readline.return_value = 'bar' handle.readlines.return_value = ['bar'] self.assertEqual(handle.read(), 'bar') self.assertEqual(handle.readline(), 'bar') self.assertEqual(handle.readlines(), ['bar']) # call repeatedly to check that a StopIteration is not propagated self.assertEqual(handle.readline(), 'bar') self.assertEqual(handle.readline(), 'bar') if __name__ == '__main__': unittest.main() mock-3.0.5/release.py000066400000000000000000000043541346437275100144640ustar00rootroot00000000000000import re from glob import glob from os.path import join from subprocess import call import blurb as blurb_module from argparse import ArgumentParser from mock import version_info VERSION_TYPES = ['major', 'minor', 'bugfix'] def incremented_version(version_info, type_): type_index = VERSION_TYPES.index(type_) version_info = tuple(e+(1 if i==type_index else 0) for i, e in enumerate(version_info)) return '.'.join(str(p) for p in version_info) def text_from_news(): # hack: blurb_module.sections.append('NEWS.d') blurbs = blurb_module.Blurbs() for path in glob(join('NEWS.d', '*')): blurbs.load_next(path) text = [] for metadata, body in blurbs: bpo = metadata['bpo'] body = f"- Issue #{bpo}: " + body text.append(blurb_module.textwrap_body(body, subsequent_indent=' ')) return '\n'.join(text) def news_to_changelog(version): with open('CHANGELOG.rst') as source: current_changelog = source.read() text = [version] text.append('-'*len(version)) text.append('') text.append(text_from_news()) text.append(current_changelog) new_changelog = '\n'.join(text) with open('CHANGELOG.rst', 'w') as target: target.write(new_changelog) def update_version(new_version): path = join('mock', 'mock.py') with open(path) as source: text = source.read() text = re.sub("(__version__ = ')[^']+(')", r"\g<1>"+new_version+r"\2", text) with open(path, 'w') as target: target.write(text) def git(command): return call('git '+command, shell=True) def git_commit(new_version): git('rm NEWS.d/*') git('add CHANGELOG.rst') git('add mock/mock.py') git(f'commit -m "Preparing for {new_version} release."') def parse_args(): parser = ArgumentParser() parser.add_argument('type', choices=VERSION_TYPES) return parser.parse_args() def main(): args = parse_args() new_version = incremented_version(version_info, args.type) news_to_changelog(new_version) update_version(new_version) git_commit(new_version) print(f'{new_version} ready to push, please check the HEAD commit first!') if __name__ == '__main__': main() mock-3.0.5/setup.cfg000066400000000000000000000027771346437275100143220ustar00rootroot00000000000000[metadata] name = mock summary = Rolling backport of unittest.mock for all Pythons home-page = http://mock.readthedocs.org/en/latest/ description-file = README.rst author = Testing Cabal author-email = testing-in-python@lists.idyll.org license = OSI Approved :: BSD License classifier = Development Status :: 5 - Production/Stable Environment :: Console Intended Audience :: Developers License :: OSI Approved :: BSD License Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy Topic :: Software Development :: Libraries Topic :: Software Development :: Libraries :: Python Modules Topic :: Software Development :: Testing keyword = testing, test, mock, mocking, unittest, patching, stubs, fakes, doubles [options] install_requires = six funcsigs>=1;python_version<"3.3" python_requires=>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* packages = mock [options.extras_require] docs = sphinx test = pytest pytest-cov build = twine wheel blurb [bdist_wheel] universal = 1 [tool:pytest] python_files=test*.py filterwarnings = ignore::DeprecationWarning mock-3.0.5/setup.py000077500000000000000000000003621346437275100142020ustar00rootroot00000000000000import re from os.path import join import setuptools setuptools.setup( version=re.search("__version__ = '([^']+)'", open(join('mock', 'mock.py')).read()).group(1), long_description=open('README.rst').read(), ) mock-3.0.5/tox.ini000066400000000000000000000003041346437275100137740ustar00rootroot00000000000000[tox] envlist = py27,pypy,py34,py35,py36,py37,docs [testenv] commands = {envbindir}/pytest {posargs} [testenv:docs] deps = sphinx commands = {envbindir}/python setup.py build_sphinx