Skip to content

Conversation

@mariocj89
Copy link
Contributor

@mariocj89 mariocj89 commented Dec 6, 2018

When a 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.

This PR also includes a refactor via commit 1a28aab, as after the change the code became even harder to read. The refactor (as it now uses common code), also fixes the test case test_customize_wrapped_object_with_side_effect_iterable_with_default, as when adding the tests I realized that if a mock has a side effect that is an iterable and one of the values returns DEFAULT, it will default to return_value if present but not to the value in wraps, which is surprising given that if instead of an iterable it is a callable the behaviour is as expected to call wraps.
Let me know if you want me to take this to a different PR and issue, as it might be worth properly explaining it. I can also get the fix without the refactor, but it'd get quite messy, basically copying the last lines into the iterator part of side_effect.

https://bugs.python.org/issue35330

@mariocj89 mariocj89 changed the title bpo-3533: Don't call the wrapped object if side_effect is set bpo-35330: Don't call the wrapped object if side_effect is set Dec 6, 2018
Copy link
Contributor

@cjw296 cjw296 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor niggles which would be good to tweak, but this looks like a very nice piece of work!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a mock? Is it important that Real has an attribute or could this just be:

class Real(object): pass

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was indeed a bad copy-paste. 😞 .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preference -> precedence

Add more tests to validate how `wraps` interacts with other features of
mocks.
When a object is wrapped using `Mock(wraps=...)`, if an user sets a
`side_effect` in one of their methods, return the value of `side_effect`
and don't call the original object.
When a `Mock` is called, it should return looking up in the following
order: `side_effect`, `return_value`, `wraps`. If any of the first two
return `mock.DEFAULT`, lookup in the next option.

It makes no sense to check for `wraps` returning default, as it is
supposed to be the original implementation and there is nothing to
fallback to.
@mariocj89 mariocj89 force-pushed the pu/wraps-side-effect branch from 1be1416 to 08d1291 Compare December 7, 2018 17:48
@mariocj89
Copy link
Contributor Author

Thanks @cjw296, I've updated it with the suggestion. Well spotted! 👍

@cjw296 cjw296 merged commit f05df0a into python:master Dec 8, 2018
@miss-islington
Copy link
Contributor

Thanks @mariocj89 for the PR, and @cjw296 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Thanks @mariocj89 for the PR, and @cjw296 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@mariocj89 mariocj89 deleted the pu/wraps-side-effect branch December 8, 2018 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants