Skip to main content

A test utility library to help write explict side effects for mocked objects

Project description

Known Side Effects

Codacy Badge Coverage Badge PyPI pyversions PyPI version fury.io PyPI license

A test utility library to help write explict side effects for mocked objects.

Mocks side effects are manipulated by when and then functions.

mock.when(...).then(...)

To enable this extend the mock class in you tests.

import known_side_effects
from unittest.mock import Mock
...
known_side_effects.extend(Mock)

When

All parameters in the when function are used to define the expected parameters for the side effect.

mock.when('argument_one', arg='argument_two').then(...)

If the mock is called with parameters that don't match any of the specified parameter sets then an UnmatchedArguments exception is raised. The arguments have to match exactly.

E.g. Given mock.when('argument_one', arg='argument_two').then(...) when the mock is called with the parameters in the table below an UnmatchedArguments is either raised or not raised.

Parameters Raises
mock('argument_one', arg='argument_two') False
mock(arg='argument_two') True
mock('argument_one') True

Multiple sets of parameters to match can be specified.

mock.when('first_specified_argument').then(...)
mock.when('second_specified_argument').then(...)
mock.when('third_specified_argument').then(...)

Chaining

Calling the when function with exactly the same arguments will allow you to append to the responses.

mock.when('arg').then('response_one')
mock.when('arg').then('response_two')

is the same as

mock.when('arg').then('response_one').then('response_two')

Then

The then function specifies what the known side effect should do when parameters are matched. By default it will just return what has been passed into the then function.

from unittest.mock import Mock
...
response_one = Mock()
mock = Mock()

mock.when(...).then(response_one)

assert mock(...) == response_one

To raise an exception rather that return a value call then_raise rather than then. An exception will be raised instead of returned.

from unittest.mock import Mock
...
exception = Exception()
mock = Mock()

mock.when(...).then_raise(exception)

mock(...)  # Raises the exception

You can also chain the then functions to return multiple different reponses. Each response will be returned once until the last response. Once the last response is reached then that reponse will be the only thing returned.

from unittest.mock import Mock
...
exception = Exception()
response_one = Mock()
mock = Mock()

mock.when(...).then(response_one).then_raise(exception)

assert mock(...) == response_one
mock(...)  # Raises the exception
mock(...)  # Raises the exception

Otherwise

You can specify default return values on a mock by calling otherwise. If the mock is called without matching any arguments then the otherwise value will returned.

mock.when('arg').then(...).otherwise('otherwise')

assert mock('not arg') == 'otherwise'

You can also raise an exception by default

mock.when(...).then(...).otherwise_raise(Exception())

Always

You can specify the mock to always return the same response regardless of what arguments it is called with.

mock.when().always('response')

assert mock(...) == 'response'

You can also raise an exception

mock.when().always_raise(Exception())

Reset

You can reset the the known side effects on a mock by passing it the reset function.

from unittest.mock import Mock
from known_side_effects import reset
...

mock = Mock()

mock.when(...).then(...)

reset(mock)

mock(...)  # raises an UnmatchedArguments exception

Gotcha

When calling the mock after specifying multiple known side effects, the first matched set of parameters will be executed. The order of matching is the order that the known side effects are defined in. If multiple arguments are specified where one matches a super set of the other (see Matchers) then the first matched will be executed. e.g.

from unittest.mock import Mock
from known_side_effects import AnyArg
...
response_one = Mock()
response_two = Mock()
argument_one = Mock()
argument_two = Mock()

mock.when(argument_one).then(response_one)
mock.when(AnyArg()).then(response_two)
...
assert mock(argument_one) == response_one
assert mock(argument_two) == response_two

If the order of the known side effects were reversed, the mock would only ever return response_two. This is due to the fact that the Any matched will match all parameters, therefore never attempting to match argument_one as it has already found a match. e.g.

from unittest.mock import Mock
from known_side_effects import AnyArg
...
response_one = Mock()
response_two = Mock()
argument_one = Mock()
argument_two = Mock()

mock.when(AnyArg()).then(response_two)        # These two lines have swapped
mock.when(argument_one).then(response_one) # These two lines have swapped

...
# This will raise an AssertionError as calling the mock with argument_one now
# returns response_two and not response_one
assert mock(argument_one) == response_one   
assert mock(argument_two) == response_two

Matchers

Matchers can be passed to known side effects as parameters. They are implementations of hamcrest matchers. Matchers will only match a single parameter.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

known_side_effects-0.1.1.tar.gz (5.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

known_side_effects-0.1.1-py2.py3-none-any.whl (12.1 kB view details)

Uploaded Python 2Python 3

File details

Details for the file known_side_effects-0.1.1.tar.gz.

File metadata

  • Download URL: known_side_effects-0.1.1.tar.gz
  • Upload date:
  • Size: 5.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for known_side_effects-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c06038be7efc3414a0ccf6c3ca8ff70234cb7e4a10f8521cf8da5298e2790bf5
MD5 9131de6f544b90f7129a23bc6af219c6
BLAKE2b-256 bb8ec48be94c414062bbaa350533104544c4ea109becaa9d2d8da44727ca63e5

See more details on using hashes here.

File details

Details for the file known_side_effects-0.1.1-py2.py3-none-any.whl.

File metadata

  • Download URL: known_side_effects-0.1.1-py2.py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for known_side_effects-0.1.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 5a075dd6affe94d42af4a6d02c71ff821ed11e7129d1df6962f012984a42bf2b
MD5 837e69362746d6164b39bc27171e7915
BLAKE2b-256 e02429977e63a29b238795f7319bf61940822d7f917a8a42aa3d04f816e20002

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page