Package: known-side-effects
Known Side EffectsA test utility library to help write explict side effects for mocked objects.Mocks side effects are manipulated bywhenandthenfunctions.mock.when(...).then(...)To enable this extend the mock class in you tests.importknown_side_effectsfromunittest.mockimportMock...known_side_effects.extend(Mock)WhenAll parameters in thewhenfunction 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 anUnmatchedArgumentsexception is raised. The arguments have to match exactly.E.g. Givenmock.when('argument_one', arg='argument_two').then(...)when the mock is called with the parameters in the table below anUnmatchedArgumentsis either raised or not raised.ParametersRaisesmock('argument_one', arg='argument_two')Falsemock(arg='argument_two')Truemock('argument_one')TrueMultiple 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(...)ChainingCalling 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 asmock.when('arg').then('response_one').then('response_two')ThenThethenfunction specifies what the known side effect should do when parameters are matched. By default it will just return what has been passed into thethenfunction.fromunittest.mockimportMock...response_one=Mock()mock=Mock()mock.when(...).then(response_one)assertmock(...)==response_oneTo raise an exception rather that return a value callthen_raiserather thanthen. An exception will be raised instead of returned.fromunittest.mockimportMock...exception=Exception()mock=Mock()mock.when(...).then_raise(exception)mock(...)# Raises the exceptionYou can also chain thethenfunctions 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.fromunittest.mockimportMock...exception=Exception()response_one=Mock()mock=Mock()mock.when(...).then(response_one).then_raise(exception)assertmock(...)==response_onemock(...)# Raises the exceptionmock(...)# Raises the exceptionOtherwiseYou 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')assertmock('not arg')=='otherwise'You can also raise an exception by defaultmock.when(...).then(...).otherwise_raise(Exception())AlwaysYou can specify the mock to always return the same response regardless of what arguments it is called with.mock.when().always('response')assertmock(...)=='response'You can also raise an exceptionmock.when().always_raise(Exception())ResetYou can reset the the known side effects on a mock by passing it theresetfunction.fromunittest.mockimportMockfromknown_side_effectsimportreset...mock=Mock()mock.when(...).then(...)reset(mock)mock(...)# raises an UnmatchedArguments exceptionGotchaWhen calling themockafter 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.fromunittest.mockimportMockfromknown_side_effectsimportAnyArg...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)...assertmock(argument_one)==response_oneassertmock(argument_two)==response_twoIf the order of the known side effects were reversed, the mock would only ever returnresponse_two. This is due to the fact that theAnymatched will match all parameters, therefore never attempting to matchargument_oneas it has already found a match. e.g.fromunittest.mockimportMockfromknown_side_effectsimportAnyArg...response_one=Mock()response_two=Mock()argument_one=Mock()argument_two=Mock()mock.when(AnyArg()).then(response_two)# These two lines have swappedmock.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_oneassertmock(argument_one)==response_oneassertmock(argument_two)==response_twoMatchersMatchers can be passed to known side effects as parameters. They are implementations ofhamcrest matchers. Matchers will only match a single parameter.