New upstream release.
This commit is contained in:
parent
cc3055ebc3
commit
506682a7c5
23
.travis.yml
23
.travis.yml
|
@ -1,14 +1,22 @@
|
|||
language: python
|
||||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6-dev"
|
||||
- "3.6"
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- python: '3.6'
|
||||
env: TOXENV=linting
|
||||
|
||||
install:
|
||||
- pip install tox coveralls
|
||||
- pip install tox-travis coveralls
|
||||
|
||||
script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != 3.6-dev ]]; then tox; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 3.6-dev ]]; then tox -e py36-pytest28,py36-pytest29,py36-pytest30; fi
|
||||
- tox
|
||||
|
||||
after_success:
|
||||
- coveralls
|
||||
|
@ -16,10 +24,11 @@ after_success:
|
|||
deploy:
|
||||
provider: pypi
|
||||
user: nicoddemus
|
||||
skip_upload_docs: true
|
||||
distributions: sdist bdist_wheel
|
||||
password:
|
||||
secure: bB4adUZVIkt31cmNklskyIDNehujKToGnStnlunp7P8CBF6CGeNqkYU17emAPvfZbTb/ClUpiO9r6AD1ej32Uyr+I8qUyhuYtHG3JGp+WRR/tw+ytAZIJ9i+PMjBv1RAdyLENJ/Tx0LKHKsABr8dQIieLFqKZJuT77f/5ZkvI/U=
|
||||
secure: OEWrbk09CZRrwFE6sBpRqQHu45zRu1S0Ly1ZeprkFCKxMd9tZOnrYM5qxCDQXxFHIvuyajuJ+qWTOgxUvurQMNsD6DbvJKTJ0R8upH1b1Q95KK8xiJFedhqBEUga5GrInK59oo0Sgblse2jtH5NnHXRUClSdT+iHdLY5sljCTRg=
|
||||
on:
|
||||
tags: true
|
||||
distributions: sdist bdist_wheel
|
||||
repo: pytest-dev/pytest-mock
|
||||
condition: $TRAVIS_PYTHON_VERSION = 3.5
|
||||
condition: $TRAVIS_PYTHON_VERSION = 3.6
|
||||
|
|
|
@ -1,5 +1,74 @@
|
|||
1.3
|
||||
---
|
||||
1.6.3
|
||||
-----
|
||||
|
||||
* Fix ``UnicodeDecodeError`` during assert introspection in ``assert_called_with`` in Python 2.
|
||||
Thanks `@AndreasHogstrom`_ for the report (`#91`_).
|
||||
|
||||
|
||||
.. _@AndreasHogstrom: https://github.com/AndreasHogstrom
|
||||
|
||||
.. _#91: https://github.com/pytest-dev/pytest-mock/issues/91
|
||||
|
||||
1.6.2
|
||||
-----
|
||||
|
||||
* Provide source package in ``tar.gz`` format and remove obsolete ``MANIFEST.in``.
|
||||
|
||||
1.6.1
|
||||
-----
|
||||
|
||||
* Fix ``mocker.resetall()`` by ignoring mocker objects which don't have a
|
||||
``resetall`` method, like for example ``patch.dict``.
|
||||
Thanks `@jdavisp3`_ for the PR (`#88`_).
|
||||
|
||||
.. _@jdavisp3: https://github.com/jdavisp3
|
||||
|
||||
.. _#88: https://github.com/pytest-dev/pytest-mock/pull/88
|
||||
|
||||
1.6.0
|
||||
-----
|
||||
|
||||
* The original assertions raised by the various ``Mock.assert_*`` methods
|
||||
now appear in the failure message, in addition to the message obtained from
|
||||
pytest introspection.
|
||||
Thanks `@quodlibetor`_ for the initial patch (`#79`_).
|
||||
|
||||
.. _@quodlibetor: https://github.com/quodlibetor
|
||||
|
||||
.. _#79: https://github.com/pytest-dev/pytest-mock/pull/79
|
||||
|
||||
1.5.0
|
||||
-----
|
||||
|
||||
* New ``mocker.mock_module`` variable points to the underlying mock module being used
|
||||
(``unittest.mock`` or ``mock``).
|
||||
Thanks `@blueyed`_ for the request (`#71`_).
|
||||
|
||||
.. _#71: https://github.com/pytest-dev/pytest-mock/pull/71
|
||||
|
||||
1.4.0
|
||||
-----
|
||||
|
||||
* New configuration variable, ``mock_use_standalone_module`` (defaults to ``False``). This forces
|
||||
the plugin to import ``mock`` instead of ``unittest.mock`` on Python 3. This is useful to import
|
||||
a newer version than the one available in the Python distribution.
|
||||
|
||||
* Previously the plugin would first try to import ``mock`` and fallback to ``unittest.mock``
|
||||
in case of an ``ImportError``, but this behavior has been removed because it could hide
|
||||
hard to debug import errors (`#68`_).
|
||||
|
||||
* Now ``mock`` (Python 2) and ``unittest.mock`` (Python 3) are lazy-loaded to make it possible to
|
||||
implement the new ``mock_use_standlone_module`` configuration option. As a consequence of this
|
||||
the undocumented ``pytest_mock.mock_module`` variable, which pointed to the actual mock module
|
||||
being used by the plugin, has been removed.
|
||||
|
||||
* `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ is now available from
|
||||
the ``mocker`` fixture.
|
||||
|
||||
.. _#68: https://github.com/pytest-dev/pytest-mock/issues/68
|
||||
|
||||
1.3.0
|
||||
-----
|
||||
|
||||
* Add support for Python 3.6. Thanks `@hackebrot`_ for the report (`#59`_).
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
include README.md
|
||||
include LICENSE
|
99
PKG-INFO
99
PKG-INFO
|
@ -1,6 +1,6 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: pytest-mock
|
||||
Version: 1.3.0
|
||||
Version: 1.6.3
|
||||
Summary: Thin-wrapper around the mock package for easier use with py.test
|
||||
Home-page: https://github.com/pytest-dev/pytest-mock/
|
||||
Author: Bruno Oliveira
|
||||
|
@ -17,7 +17,14 @@ Description: ===========
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
import os
|
||||
|
||||
class UnixFS:
|
||||
|
||||
@staticmethod
|
||||
def rm(filename):
|
||||
os.remove(filename)
|
||||
|
||||
def test_unix_fs(mocker):
|
||||
mocker.patch('os.remove')
|
||||
UnixFS.rm('file')
|
||||
|
@ -26,21 +33,21 @@ Description: ===========
|
|||
|
||||
.. Using PNG badges because PyPI doesn't support SVG
|
||||
|
||||
|python| |version| |downloads| |ci| |appveyor| |coverage|
|
||||
|python| |version| |anaconda| |ci| |appveyor| |coverage|
|
||||
|
||||
.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.png
|
||||
.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
|
||||
:target: https://pypi.python.org/pypi/pytest-mock
|
||||
|
||||
.. |downloads| image:: http://img.shields.io/pypi/dm/pytest-mock.png
|
||||
:target: https://pypi.python.org/pypi/pytest-mock
|
||||
.. |anaconda| image:: https://anaconda.org/conda-forge/pytest-mock/badges/version.svg
|
||||
:target: https://anaconda.org/conda-forge/pytest-mock
|
||||
|
||||
.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.png
|
||||
.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.svg
|
||||
:target: https://travis-ci.org/pytest-dev/pytest-mock
|
||||
|
||||
.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/pid1t7iuwhkm9eh6/branch/master?svg=true
|
||||
:target: https://ci.appveyor.com/project/pytestbot/pytest-mock
|
||||
|
||||
.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.png
|
||||
.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.svg
|
||||
:target: https://coveralls.io/r/pytest-dev/pytest-mock
|
||||
|
||||
.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
|
||||
|
@ -76,6 +83,7 @@ Description: ===========
|
|||
* `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
|
||||
* `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
|
||||
* `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
|
||||
* `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
|
||||
* `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
|
||||
* `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
|
||||
* `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
|
||||
|
@ -133,14 +141,30 @@ Description: ===========
|
|||
diff::
|
||||
|
||||
|
||||
m = mocker.patch.object(DS, 'create_char')
|
||||
DS().create_char('Raistlin', class_='mag', gift=12)
|
||||
> m.assert_called_once_with('Raistlin', class_='mage', gift=12)
|
||||
E assert {'class_': 'mag', 'gift': 12} == {'class_': 'mage', 'gift': 12}
|
||||
E Omitting 1 identical items, use -v to show
|
||||
E Differing items:
|
||||
E {'class_': 'mag'} != {'class_': 'mage'}
|
||||
mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
|
||||
|
||||
def test(mocker):
|
||||
m = mocker.Mock()
|
||||
m('fo')
|
||||
> m.assert_called_once_with('', bar=4)
|
||||
E AssertionError: Expected call: mock('', bar=4)
|
||||
E Actual call: mock('fo')
|
||||
E
|
||||
E pytest introspection follows:
|
||||
E
|
||||
E Args:
|
||||
E assert ('fo',) == ('',)
|
||||
E At index 0 diff: 'fo' != ''
|
||||
E Use -v to get the full diff
|
||||
E Kwargs:
|
||||
E assert {} == {'bar': 4}
|
||||
E Right contains more items:
|
||||
E {'bar': 4}
|
||||
E Use -v to get the full diff
|
||||
|
||||
|
||||
test_foo.py:6: AssertionError
|
||||
========================== 1 failed in 0.03 seconds ===========================
|
||||
|
||||
|
||||
This is useful when asserting mock calls with many/nested arguments and trying
|
||||
|
@ -158,7 +182,25 @@ Description: ===========
|
|||
mechanism used to suppress traceback entries from ``mock`` module does not work with that option
|
||||
anyway plus it generates confusing messages on Python 3.5 due to exception chaining
|
||||
|
||||
.. _advanced assertions: https://pytest.org/latest/assert.html
|
||||
.. _advanced assertions: http://pytest.org/latest/assert.html
|
||||
|
||||
|
||||
Use standalone "mock" package
|
||||
-----------------------------
|
||||
|
||||
*New in version 1.4.0.*
|
||||
|
||||
Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
|
||||
than the one that comes with the Python distribution.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
mock_use_standalone_module = true
|
||||
|
||||
This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
|
||||
Python 3.3+. Note that this option is only used in Python 3+, as Python 2 users only have the option
|
||||
to use the ``mock`` package from PyPI anyway.
|
||||
|
||||
|
||||
Requirements
|
||||
|
@ -240,9 +282,13 @@ Description: ===========
|
|||
- you can't easily undo the mocking during the test execution;
|
||||
|
||||
|
||||
**Note**
|
||||
**Note about usage as context manager**
|
||||
|
||||
Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as context managers and function decorators are **not** supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in ``mocker`` in this manner can lead to non-intuitive errors:
|
||||
Although mocker's API is intentionally the same as ``mock.patch``'s, its use
|
||||
as context manager and function decorator is **not** supported through the
|
||||
fixture. The purpose of this plugin is to make the use of context managers and
|
||||
function decorators for mocking unnecessary. Indeed, trying to use the
|
||||
functionality in ``mocker`` in this manner can lead to non-intuitive errors:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -259,6 +305,23 @@ Description: ===========
|
|||
with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
|
||||
E AttributeError: __exit__
|
||||
|
||||
You can however use ``mocker.mock_module`` to access the underlying ``mock``
|
||||
module, e.g. to return a context manager in a fixture that mocks something
|
||||
temporarily:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def fixture_cm(mocker):
|
||||
@contextlib.contextmanager
|
||||
def my_cm():
|
||||
def mocked():
|
||||
pass
|
||||
|
||||
with mocker.mock_module.patch.object(SomeClass, 'method', mocked):
|
||||
yield
|
||||
return my_cm
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
|
97
README.rst
97
README.rst
|
@ -9,7 +9,14 @@ of a test:
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
import os
|
||||
|
||||
class UnixFS:
|
||||
|
||||
@staticmethod
|
||||
def rm(filename):
|
||||
os.remove(filename)
|
||||
|
||||
def test_unix_fs(mocker):
|
||||
mocker.patch('os.remove')
|
||||
UnixFS.rm('file')
|
||||
|
@ -18,21 +25,21 @@ of a test:
|
|||
|
||||
.. Using PNG badges because PyPI doesn't support SVG
|
||||
|
||||
|python| |version| |downloads| |ci| |appveyor| |coverage|
|
||||
|python| |version| |anaconda| |ci| |appveyor| |coverage|
|
||||
|
||||
.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.png
|
||||
.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
|
||||
:target: https://pypi.python.org/pypi/pytest-mock
|
||||
|
||||
.. |downloads| image:: http://img.shields.io/pypi/dm/pytest-mock.png
|
||||
:target: https://pypi.python.org/pypi/pytest-mock
|
||||
.. |anaconda| image:: https://anaconda.org/conda-forge/pytest-mock/badges/version.svg
|
||||
:target: https://anaconda.org/conda-forge/pytest-mock
|
||||
|
||||
.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.png
|
||||
.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.svg
|
||||
:target: https://travis-ci.org/pytest-dev/pytest-mock
|
||||
|
||||
.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/pid1t7iuwhkm9eh6/branch/master?svg=true
|
||||
:target: https://ci.appveyor.com/project/pytestbot/pytest-mock
|
||||
|
||||
.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.png
|
||||
.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.svg
|
||||
:target: https://coveralls.io/r/pytest-dev/pytest-mock
|
||||
|
||||
.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
|
||||
|
@ -68,6 +75,7 @@ Some objects from the ``mock`` module are accessible directly from ``mocker`` fo
|
|||
* `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
|
||||
* `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
|
||||
* `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
|
||||
* `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
|
||||
* `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
|
||||
* `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
|
||||
* `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
|
||||
|
@ -125,14 +133,30 @@ the method, and uses py.test's own `advanced assertions`_ to return a better
|
|||
diff::
|
||||
|
||||
|
||||
m = mocker.patch.object(DS, 'create_char')
|
||||
DS().create_char('Raistlin', class_='mag', gift=12)
|
||||
> m.assert_called_once_with('Raistlin', class_='mage', gift=12)
|
||||
E assert {'class_': 'mag', 'gift': 12} == {'class_': 'mage', 'gift': 12}
|
||||
E Omitting 1 identical items, use -v to show
|
||||
E Differing items:
|
||||
E {'class_': 'mag'} != {'class_': 'mage'}
|
||||
mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
|
||||
|
||||
def test(mocker):
|
||||
m = mocker.Mock()
|
||||
m('fo')
|
||||
> m.assert_called_once_with('', bar=4)
|
||||
E AssertionError: Expected call: mock('', bar=4)
|
||||
E Actual call: mock('fo')
|
||||
E
|
||||
E pytest introspection follows:
|
||||
E
|
||||
E Args:
|
||||
E assert ('fo',) == ('',)
|
||||
E At index 0 diff: 'fo' != ''
|
||||
E Use -v to get the full diff
|
||||
E Kwargs:
|
||||
E assert {} == {'bar': 4}
|
||||
E Right contains more items:
|
||||
E {'bar': 4}
|
||||
E Use -v to get the full diff
|
||||
|
||||
|
||||
test_foo.py:6: AssertionError
|
||||
========================== 1 failed in 0.03 seconds ===========================
|
||||
|
||||
|
||||
This is useful when asserting mock calls with many/nested arguments and trying
|
||||
|
@ -150,7 +174,25 @@ Note that this feature is automatically disabled with the ``--tb=native`` option
|
|||
mechanism used to suppress traceback entries from ``mock`` module does not work with that option
|
||||
anyway plus it generates confusing messages on Python 3.5 due to exception chaining
|
||||
|
||||
.. _advanced assertions: https://pytest.org/latest/assert.html
|
||||
.. _advanced assertions: http://pytest.org/latest/assert.html
|
||||
|
||||
|
||||
Use standalone "mock" package
|
||||
-----------------------------
|
||||
|
||||
*New in version 1.4.0.*
|
||||
|
||||
Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
|
||||
than the one that comes with the Python distribution.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
mock_use_standalone_module = true
|
||||
|
||||
This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
|
||||
Python 3.3+. Note that this option is only used in Python 3+, as Python 2 users only have the option
|
||||
to use the ``mock`` package from PyPI anyway.
|
||||
|
||||
|
||||
Requirements
|
||||
|
@ -232,9 +274,13 @@ But this poses a few disadvantages:
|
|||
- you can't easily undo the mocking during the test execution;
|
||||
|
||||
|
||||
**Note**
|
||||
**Note about usage as context manager**
|
||||
|
||||
Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as context managers and function decorators are **not** supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in ``mocker`` in this manner can lead to non-intuitive errors:
|
||||
Although mocker's API is intentionally the same as ``mock.patch``'s, its use
|
||||
as context manager and function decorator is **not** supported through the
|
||||
fixture. The purpose of this plugin is to make the use of context managers and
|
||||
function decorators for mocking unnecessary. Indeed, trying to use the
|
||||
functionality in ``mocker`` in this manner can lead to non-intuitive errors:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -251,6 +297,23 @@ Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as
|
|||
with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
|
||||
E AttributeError: __exit__
|
||||
|
||||
You can however use ``mocker.mock_module`` to access the underlying ``mock``
|
||||
module, e.g. to return a context manager in a fixture that mocks something
|
||||
temporarily:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def fixture_cm(mocker):
|
||||
@contextlib.contextmanager
|
||||
def my_cm():
|
||||
def mocked():
|
||||
pass
|
||||
|
||||
with mocker.mock_module.patch.object(SomeClass, 'method', mocked):
|
||||
yield
|
||||
return my_cm
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# coding: utf-8
|
||||
# file generated by setuptools_scm
|
||||
# don't change, don't track in version control
|
||||
version = '1.3.0'
|
||||
version = '1.6.3'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
install:
|
||||
- C:\Python35\python -m pip install tox
|
||||
- C:\Python36\python -m pip install tox
|
||||
|
||||
build: false # Not a C# project
|
||||
|
||||
test_script:
|
||||
- C:\Python35\scripts\tox
|
||||
- C:\Python36\scripts\tox
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: pytest-mock
|
||||
Version: 1.3.0
|
||||
Version: 1.6.3
|
||||
Summary: Thin-wrapper around the mock package for easier use with py.test
|
||||
Home-page: https://github.com/pytest-dev/pytest-mock/
|
||||
Author: Bruno Oliveira
|
||||
|
@ -17,7 +17,14 @@ Description: ===========
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
import os
|
||||
|
||||
class UnixFS:
|
||||
|
||||
@staticmethod
|
||||
def rm(filename):
|
||||
os.remove(filename)
|
||||
|
||||
def test_unix_fs(mocker):
|
||||
mocker.patch('os.remove')
|
||||
UnixFS.rm('file')
|
||||
|
@ -26,21 +33,21 @@ Description: ===========
|
|||
|
||||
.. Using PNG badges because PyPI doesn't support SVG
|
||||
|
||||
|python| |version| |downloads| |ci| |appveyor| |coverage|
|
||||
|python| |version| |anaconda| |ci| |appveyor| |coverage|
|
||||
|
||||
.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.png
|
||||
.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
|
||||
:target: https://pypi.python.org/pypi/pytest-mock
|
||||
|
||||
.. |downloads| image:: http://img.shields.io/pypi/dm/pytest-mock.png
|
||||
:target: https://pypi.python.org/pypi/pytest-mock
|
||||
.. |anaconda| image:: https://anaconda.org/conda-forge/pytest-mock/badges/version.svg
|
||||
:target: https://anaconda.org/conda-forge/pytest-mock
|
||||
|
||||
.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.png
|
||||
.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.svg
|
||||
:target: https://travis-ci.org/pytest-dev/pytest-mock
|
||||
|
||||
.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/pid1t7iuwhkm9eh6/branch/master?svg=true
|
||||
:target: https://ci.appveyor.com/project/pytestbot/pytest-mock
|
||||
|
||||
.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.png
|
||||
.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.svg
|
||||
:target: https://coveralls.io/r/pytest-dev/pytest-mock
|
||||
|
||||
.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
|
||||
|
@ -76,6 +83,7 @@ Description: ===========
|
|||
* `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
|
||||
* `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
|
||||
* `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
|
||||
* `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
|
||||
* `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
|
||||
* `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
|
||||
* `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
|
||||
|
@ -133,14 +141,30 @@ Description: ===========
|
|||
diff::
|
||||
|
||||
|
||||
m = mocker.patch.object(DS, 'create_char')
|
||||
DS().create_char('Raistlin', class_='mag', gift=12)
|
||||
> m.assert_called_once_with('Raistlin', class_='mage', gift=12)
|
||||
E assert {'class_': 'mag', 'gift': 12} == {'class_': 'mage', 'gift': 12}
|
||||
E Omitting 1 identical items, use -v to show
|
||||
E Differing items:
|
||||
E {'class_': 'mag'} != {'class_': 'mage'}
|
||||
mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
|
||||
|
||||
def test(mocker):
|
||||
m = mocker.Mock()
|
||||
m('fo')
|
||||
> m.assert_called_once_with('', bar=4)
|
||||
E AssertionError: Expected call: mock('', bar=4)
|
||||
E Actual call: mock('fo')
|
||||
E
|
||||
E pytest introspection follows:
|
||||
E
|
||||
E Args:
|
||||
E assert ('fo',) == ('',)
|
||||
E At index 0 diff: 'fo' != ''
|
||||
E Use -v to get the full diff
|
||||
E Kwargs:
|
||||
E assert {} == {'bar': 4}
|
||||
E Right contains more items:
|
||||
E {'bar': 4}
|
||||
E Use -v to get the full diff
|
||||
|
||||
|
||||
test_foo.py:6: AssertionError
|
||||
========================== 1 failed in 0.03 seconds ===========================
|
||||
|
||||
|
||||
This is useful when asserting mock calls with many/nested arguments and trying
|
||||
|
@ -158,7 +182,25 @@ Description: ===========
|
|||
mechanism used to suppress traceback entries from ``mock`` module does not work with that option
|
||||
anyway plus it generates confusing messages on Python 3.5 due to exception chaining
|
||||
|
||||
.. _advanced assertions: https://pytest.org/latest/assert.html
|
||||
.. _advanced assertions: http://pytest.org/latest/assert.html
|
||||
|
||||
|
||||
Use standalone "mock" package
|
||||
-----------------------------
|
||||
|
||||
*New in version 1.4.0.*
|
||||
|
||||
Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
|
||||
than the one that comes with the Python distribution.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
mock_use_standalone_module = true
|
||||
|
||||
This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
|
||||
Python 3.3+. Note that this option is only used in Python 3+, as Python 2 users only have the option
|
||||
to use the ``mock`` package from PyPI anyway.
|
||||
|
||||
|
||||
Requirements
|
||||
|
@ -240,9 +282,13 @@ Description: ===========
|
|||
- you can't easily undo the mocking during the test execution;
|
||||
|
||||
|
||||
**Note**
|
||||
**Note about usage as context manager**
|
||||
|
||||
Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as context managers and function decorators are **not** supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in ``mocker`` in this manner can lead to non-intuitive errors:
|
||||
Although mocker's API is intentionally the same as ``mock.patch``'s, its use
|
||||
as context manager and function decorator is **not** supported through the
|
||||
fixture. The purpose of this plugin is to make the use of context managers and
|
||||
function decorators for mocking unnecessary. Indeed, trying to use the
|
||||
functionality in ``mocker`` in this manner can lead to non-intuitive errors:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -259,6 +305,23 @@ Description: ===========
|
|||
with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
|
||||
E AttributeError: __exit__
|
||||
|
||||
You can however use ``mocker.mock_module`` to access the underlying ``mock``
|
||||
module, e.g. to return a context manager in a fixture that mocks something
|
||||
temporarily:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def fixture_cm(mocker):
|
||||
@contextlib.contextmanager
|
||||
def my_cm():
|
||||
def mocked():
|
||||
pass
|
||||
|
||||
with mocker.mock_module.patch.object(SomeClass, 'method', mocked):
|
||||
yield
|
||||
return my_cm
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
.travis.yml
|
||||
CHANGELOG.rst
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README.rst
|
||||
_pytest_mock_version.py
|
||||
appveyor.yml
|
||||
|
|
107
pytest_mock.py
107
pytest_mock.py
|
@ -1,15 +1,38 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
try:
|
||||
import mock as mock_module
|
||||
except ImportError:
|
||||
import unittest.mock as mock_module
|
||||
|
||||
from _pytest_mock_version import version
|
||||
|
||||
__version__ = version
|
||||
|
||||
# pseudo-six; if this starts to require more than this, depend on six already
|
||||
if sys.version_info[0] == 2: # pragma: no cover
|
||||
text_type = unicode # noqa
|
||||
else:
|
||||
text_type = str
|
||||
|
||||
|
||||
def _get_mock_module(config):
|
||||
"""
|
||||
Import and return the actual "mock" module. By default this is "mock" for Python 2 and
|
||||
"unittest.mock" for Python 3, but the user can force to always use "mock" on Python 3 using
|
||||
the mock_use_standalone_module ini option.
|
||||
"""
|
||||
if not hasattr(_get_mock_module, '_module'):
|
||||
use_standalone_module = parse_ini_boolean(config.getini('mock_use_standalone_module'))
|
||||
if sys.version_info[0] == 2 or use_standalone_module:
|
||||
import mock
|
||||
_get_mock_module._module = mock
|
||||
else:
|
||||
import unittest.mock
|
||||
_get_mock_module._module = unittest.mock
|
||||
|
||||
return _get_mock_module._module
|
||||
|
||||
|
||||
class MockFixture(object):
|
||||
"""
|
||||
|
@ -17,20 +40,18 @@ class MockFixture(object):
|
|||
ensuring that they are uninstalled at the end of each test.
|
||||
"""
|
||||
|
||||
Mock = mock_module.Mock
|
||||
MagicMock = mock_module.MagicMock
|
||||
PropertyMock = mock_module.PropertyMock
|
||||
call = mock_module.call
|
||||
ANY = mock_module.ANY
|
||||
sentinel = mock_module.sentinel
|
||||
mock_open = mock_module.mock_open
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, config):
|
||||
self._patches = [] # list of mock._patch objects
|
||||
self._mocks = [] # list of MagicMock objects
|
||||
self.patch = self._Patcher(self._patches, self._mocks)
|
||||
# temporary fix: this should be at class level, but is blowing
|
||||
# up in Python 3.6
|
||||
self.mock_module = mock_module = _get_mock_module(config)
|
||||
self.patch = self._Patcher(self._patches, self._mocks, mock_module)
|
||||
# aliases for convenience
|
||||
self.Mock = mock_module.Mock
|
||||
self.MagicMock = mock_module.MagicMock
|
||||
self.PropertyMock = mock_module.PropertyMock
|
||||
self.call = mock_module.call
|
||||
self.ANY = mock_module.ANY
|
||||
self.DEFAULT = mock_module.DEFAULT
|
||||
self.sentinel = mock_module.sentinel
|
||||
self.mock_open = mock_module.mock_open
|
||||
|
||||
|
@ -90,7 +111,7 @@ class MockFixture(object):
|
|||
:rtype: mock.MagicMock
|
||||
:return: Stub object.
|
||||
"""
|
||||
return mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name)
|
||||
return self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name)
|
||||
|
||||
class _Patcher(object):
|
||||
"""
|
||||
|
@ -98,9 +119,10 @@ class MockFixture(object):
|
|||
etc. We need this indirection to keep the same API of the mock package.
|
||||
"""
|
||||
|
||||
def __init__(self, patches, mocks):
|
||||
def __init__(self, patches, mocks, mock_module):
|
||||
self._patches = patches
|
||||
self._mocks = mocks
|
||||
self.mock_module = mock_module
|
||||
|
||||
def _start_patch(self, mock_func, *args, **kwargs):
|
||||
"""Patches something by calling the given function from the mock
|
||||
|
@ -110,34 +132,35 @@ class MockFixture(object):
|
|||
p = mock_func(*args, **kwargs)
|
||||
mocked = p.start()
|
||||
self._patches.append(p)
|
||||
self._mocks.append(mocked)
|
||||
if hasattr(mocked, 'reset_mock'):
|
||||
self._mocks.append(mocked)
|
||||
return mocked
|
||||
|
||||
def object(self, *args, **kwargs):
|
||||
"""API to mock.patch.object"""
|
||||
return self._start_patch(mock_module.patch.object, *args, **kwargs)
|
||||
return self._start_patch(self.mock_module.patch.object, *args, **kwargs)
|
||||
|
||||
def multiple(self, *args, **kwargs):
|
||||
"""API to mock.patch.multiple"""
|
||||
return self._start_patch(mock_module.patch.multiple, *args,
|
||||
return self._start_patch(self.mock_module.patch.multiple, *args,
|
||||
**kwargs)
|
||||
|
||||
def dict(self, *args, **kwargs):
|
||||
"""API to mock.patch.dict"""
|
||||
return self._start_patch(mock_module.patch.dict, *args, **kwargs)
|
||||
return self._start_patch(self.mock_module.patch.dict, *args, **kwargs)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
"""API to mock.patch"""
|
||||
return self._start_patch(mock_module.patch, *args, **kwargs)
|
||||
return self._start_patch(self.mock_module.patch, *args, **kwargs)
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def mocker():
|
||||
def mocker(pytestconfig):
|
||||
"""
|
||||
return an object that has the same interface to the `mock` module, but
|
||||
takes care of automatically undoing all patches after each test method.
|
||||
"""
|
||||
result = MockFixture()
|
||||
result = MockFixture(pytestconfig)
|
||||
yield result
|
||||
result.stopall()
|
||||
|
||||
|
@ -161,13 +184,27 @@ def assert_wrapper(__wrapped_mock_method__, *args, **kwargs):
|
|||
__tracebackhide__ = True
|
||||
try:
|
||||
__wrapped_mock_method__(*args, **kwargs)
|
||||
return
|
||||
except AssertionError as e:
|
||||
__mock_self = args[0]
|
||||
if __mock_self.call_args is not None:
|
||||
actual_args, actual_kwargs = __mock_self.call_args
|
||||
assert actual_args == args[1:]
|
||||
assert actual_kwargs == kwargs
|
||||
raise AssertionError(*e.args)
|
||||
if getattr(e, '_mock_introspection_applied', 0):
|
||||
msg = text_type(e)
|
||||
else:
|
||||
__mock_self = args[0]
|
||||
msg = text_type(e)
|
||||
if __mock_self.call_args is not None:
|
||||
actual_args, actual_kwargs = __mock_self.call_args
|
||||
msg += '\n\npytest introspection follows:\n'
|
||||
try:
|
||||
assert actual_args == args[1:]
|
||||
except AssertionError as e:
|
||||
msg += '\nArgs:\n' + text_type(e)
|
||||
try:
|
||||
assert actual_kwargs == kwargs
|
||||
except AssertionError as e:
|
||||
msg += '\nKwargs:\n' + text_type(e)
|
||||
e = AssertionError(msg)
|
||||
e._mock_introspection_applied = True
|
||||
raise e
|
||||
|
||||
|
||||
def wrap_assert_not_called(*args, **kwargs):
|
||||
|
@ -209,6 +246,8 @@ def wrap_assert_methods(config):
|
|||
if _mock_module_originals:
|
||||
return
|
||||
|
||||
mock_module = _get_mock_module(config)
|
||||
|
||||
wrappers = {
|
||||
'assert_not_called': wrap_assert_not_called,
|
||||
'assert_called_with': wrap_assert_called_with,
|
||||
|
@ -247,6 +286,10 @@ def pytest_addoption(parser):
|
|||
'Monkeypatch the mock library to improve reporting of the '
|
||||
'assert_called_... methods',
|
||||
default=True)
|
||||
parser.addini('mock_use_standalone_module',
|
||||
'Use standalone "mock" (from PyPI) instead of builtin "unittest.mock" '
|
||||
'on Python 3',
|
||||
default=False)
|
||||
|
||||
|
||||
def parse_ini_boolean(value):
|
||||
|
|
|
@ -4,5 +4,4 @@ universal = 1
|
|||
[egg_info]
|
||||
tag_build =
|
||||
tag_date = 0
|
||||
tag_svn_revision = 0
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import sys
|
|||
from contextlib import contextmanager
|
||||
|
||||
import py.code
|
||||
|
||||
import pytest
|
||||
|
||||
pytest_plugins = 'pytester'
|
||||
|
@ -69,10 +68,8 @@ def mock_using_patch(mocker):
|
|||
|
||||
|
||||
def mock_using_patch_multiple(mocker):
|
||||
from pytest_mock import mock_module
|
||||
|
||||
r = mocker.patch.multiple('os', remove=mock_module.DEFAULT,
|
||||
listdir=mock_module.DEFAULT)
|
||||
r = mocker.patch.multiple('os', remove=mocker.DEFAULT,
|
||||
listdir=mocker.DEFAULT)
|
||||
return r['remove'], r['listdir']
|
||||
|
||||
|
||||
|
@ -89,6 +86,8 @@ def test_mock_patches(mock_fs, mocker, check_unix_fs_mocked):
|
|||
mock_fs(mocker)
|
||||
mocked_rm, mocked_ls = mock_fs(mocker)
|
||||
check_unix_fs_mocked(mocked_rm, mocked_ls)
|
||||
mocker.resetall()
|
||||
mocker.stopall()
|
||||
|
||||
|
||||
def test_mock_patch_dict(mocker):
|
||||
|
@ -103,23 +102,16 @@ def test_mock_patch_dict(mocker):
|
|||
assert x == {'original': 1}
|
||||
|
||||
|
||||
def test_mock_fixture_is_deprecated(testdir):
|
||||
def test_mock_patch_dict_resetall(mocker):
|
||||
"""
|
||||
Test that a warning emitted when using deprecated "mock" fixture.
|
||||
We can call resetall after patching a dict.
|
||||
:param mock:
|
||||
"""
|
||||
testdir.makepyfile('''
|
||||
import warnings
|
||||
import os
|
||||
warnings.simplefilter('always')
|
||||
|
||||
def test_foo(mock, tmpdir):
|
||||
mock.patch('os.listdir', return_value=['mocked'])
|
||||
assert os.listdir(str(tmpdir)) == ['mocked']
|
||||
mock.stopall()
|
||||
assert os.listdir(str(tmpdir)) == []
|
||||
''')
|
||||
result = testdir.runpytest('-s')
|
||||
result.stderr.fnmatch_lines(['*"mock" fixture has been deprecated*'])
|
||||
x = {'original': 1}
|
||||
mocker.patch.dict(x, values=[('new', 10)], clear=True)
|
||||
assert x == {'new': 10}
|
||||
mocker.resetall()
|
||||
assert x == {'new': 10}
|
||||
|
||||
|
||||
def test_deprecated_mock(mock, tmpdir):
|
||||
|
@ -133,10 +125,12 @@ def test_deprecated_mock(mock, tmpdir):
|
|||
|
||||
|
||||
@pytest.mark.parametrize('name', ['MagicMock', 'PropertyMock', 'Mock', 'call', 'ANY', 'sentinel', 'mock_open'])
|
||||
def test_mocker_aliases(name):
|
||||
from pytest_mock import mock_module, MockFixture
|
||||
def test_mocker_aliases(name, pytestconfig):
|
||||
from pytest_mock import _get_mock_module, MockFixture
|
||||
|
||||
mocker = MockFixture()
|
||||
mock_module = _get_mock_module(pytestconfig)
|
||||
|
||||
mocker = MockFixture(pytestconfig)
|
||||
assert getattr(mocker, name) is getattr(mock_module, name)
|
||||
|
||||
|
||||
|
@ -203,8 +197,6 @@ def test_instance_method_spy(mocker):
|
|||
|
||||
@skip_pypy
|
||||
def test_instance_method_by_class_spy(mocker):
|
||||
from pytest_mock import mock_module
|
||||
|
||||
class Foo(object):
|
||||
|
||||
def bar(self, arg):
|
||||
|
@ -215,13 +207,12 @@ def test_instance_method_by_class_spy(mocker):
|
|||
other = Foo()
|
||||
assert foo.bar(arg=10) == 20
|
||||
assert other.bar(arg=10) == 20
|
||||
calls = [mock_module.call(foo, arg=10), mock_module.call(other, arg=10)]
|
||||
calls = [mocker.call(foo, arg=10), mocker.call(other, arg=10)]
|
||||
assert spy.call_args_list == calls
|
||||
|
||||
|
||||
@skip_pypy
|
||||
def test_instance_method_by_subclass_spy(mocker):
|
||||
from pytest_mock import mock_module
|
||||
|
||||
class Base(object):
|
||||
|
||||
|
@ -236,7 +227,7 @@ def test_instance_method_by_subclass_spy(mocker):
|
|||
other = Foo()
|
||||
assert foo.bar(arg=10) == 20
|
||||
assert other.bar(arg=10) == 20
|
||||
calls = [mock_module.call(foo, arg=10), mock_module.call(other, arg=10)]
|
||||
calls = [mocker.call(foo, arg=10), mocker.call(other, arg=10)]
|
||||
assert spy.call_args_list == calls
|
||||
|
||||
|
||||
|
@ -424,12 +415,11 @@ def test_assert_any_call_wrapper(mocker):
|
|||
|
||||
|
||||
def test_assert_has_calls(mocker):
|
||||
from pytest_mock import mock_module
|
||||
stub = mocker.stub()
|
||||
stub("foo")
|
||||
stub.assert_has_calls([mock_module.call("foo")])
|
||||
stub.assert_has_calls([mocker.call("foo")])
|
||||
with assert_traceback():
|
||||
stub.assert_has_calls([mock_module.call("bar")])
|
||||
stub.assert_has_calls([mocker.call("bar")])
|
||||
|
||||
|
||||
def test_monkeypatch_ini(mocker, testdir):
|
||||
|
@ -447,11 +437,7 @@ def test_monkeypatch_ini(mocker, testdir):
|
|||
[pytest]
|
||||
mock_traceback_monkeypatch = false
|
||||
""")
|
||||
if hasattr(testdir, 'runpytest_subprocess'):
|
||||
result = testdir.runpytest_subprocess()
|
||||
else:
|
||||
# pytest 2.7.X
|
||||
result = testdir.runpytest()
|
||||
result = runpytest_subprocess(testdir)
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
|
@ -487,14 +473,74 @@ def test_monkeypatch_native(testdir):
|
|||
stub(1, greet='hello')
|
||||
stub.assert_called_once_with(1, greet='hey')
|
||||
""")
|
||||
if hasattr(testdir, 'runpytest_subprocess'):
|
||||
result = testdir.runpytest_subprocess('--tb=native')
|
||||
else:
|
||||
# pytest 2.7.X
|
||||
result = testdir.runpytest('--tb=native')
|
||||
result = runpytest_subprocess(testdir, '--tb=native')
|
||||
assert result.ret == 1
|
||||
assert 'During handling of the above exception' not in result.stdout.str()
|
||||
assert 'Differing items:' not in result.stdout.str()
|
||||
traceback_lines = [x for x in result.stdout.str().splitlines()
|
||||
if 'Traceback (most recent call last)' in x]
|
||||
assert len(traceback_lines) == 1 # make sure there are no duplicated tracebacks (#44)
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info[0] < 3, reason='Py3 only')
|
||||
def test_standalone_mock(testdir):
|
||||
"""Check that the "mock_use_standalone" is being used.
|
||||
"""
|
||||
testdir.makepyfile("""
|
||||
def test_foo(mocker):
|
||||
pass
|
||||
""")
|
||||
testdir.makeini("""
|
||||
[pytest]
|
||||
mock_use_standalone_module = true
|
||||
""")
|
||||
result = runpytest_subprocess(testdir)
|
||||
assert result.ret == 3
|
||||
result.stderr.fnmatch_lines([
|
||||
"*No module named 'mock'*",
|
||||
])
|
||||
|
||||
|
||||
def runpytest_subprocess(testdir, *args):
|
||||
"""Testdir.runpytest_subprocess only available in pytest-2.8+"""
|
||||
if hasattr(testdir, 'runpytest_subprocess'):
|
||||
return testdir.runpytest_subprocess(*args)
|
||||
else:
|
||||
# pytest 2.7.X
|
||||
return testdir.runpytest(*args)
|
||||
|
||||
|
||||
def test_detailed_introspection(testdir):
|
||||
"""Check that the "mock_use_standalone" is being used.
|
||||
"""
|
||||
testdir.makepyfile("""
|
||||
def test(mocker):
|
||||
m = mocker.Mock()
|
||||
m('fo')
|
||||
m.assert_called_once_with('', bar=4)
|
||||
""")
|
||||
result = testdir.runpytest('-s')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*AssertionError: Expected call: mock('', bar=4)*",
|
||||
"*Actual call: mock('fo')*",
|
||||
"*pytest introspection follows:*",
|
||||
'*Args:',
|
||||
"*assert ('fo',) == ('',)",
|
||||
"*At index 0 diff: 'fo' != ''*",
|
||||
"*Use -v to get the full diff*",
|
||||
"*Kwargs:*",
|
||||
"*assert {} == {'bar': 4}*",
|
||||
"*Right contains more items:*",
|
||||
"*{'bar': 4}*",
|
||||
"*Use -v to get the full diff*",
|
||||
])
|
||||
|
||||
|
||||
def test_assert_called_with_unicode_arguments(mocker):
|
||||
"""Test bug in assert_call_with called with non-ascii unicode string (#91)"""
|
||||
stub = mocker.stub()
|
||||
stub(b'l\xc3\xb6k'.decode('UTF-8'))
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
stub.assert_called_with(u'lak')
|
||||
|
||||
|
|
3
tox.ini
3
tox.ini
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = py{26,27,33,34,35}-pytest{27,28,29,30},linting
|
||||
envlist = py{26,27,33,34,35,36}-pytest{27,28,29,30},linting
|
||||
|
||||
[testenv]
|
||||
passenv = USER USERNAME
|
||||
|
@ -13,7 +13,6 @@ commands =
|
|||
coverage run --append --source=pytest_mock.py -m pytest test_pytest_mock.py
|
||||
|
||||
[testenv:linting]
|
||||
basepython = python3.5
|
||||
skip_install=True
|
||||
deps =
|
||||
pytest-flakes
|
||||
|
|
Loading…
Reference in a new issue