summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Foord <michael@voidspace.org.uk>2012-06-10 20:29:40 +0100
committerMichael Foord <michael@voidspace.org.uk>2012-06-10 20:29:40 +0100
commitcdb469a592d6c87227fed25085874361332f728b (patch)
tree91c4e853e89d8953635c865dc6e99012344d4681
parent1ed46f2879108a9f59569abc92b127edfa6bda99 (diff)
downloadmock-cdb469a592d6c87227fed25085874361332f728b.tar.gz
Adding patch.stopall method
-rw-r--r--docs/changelog.txt1
-rw-r--r--docs/patch.txt8
-rw-r--r--mock.py22
-rw-r--r--tests/testpatch.py19
4 files changed, 46 insertions, 4 deletions
diff --git a/docs/changelog.txt b/docs/changelog.txt
index cc990f2..1d8d30c 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -7,6 +7,7 @@ CHANGELOG
2012/XX/XX Version 1.0.0 alpha 3
--------------------------------
+* Added `patch.stopall` method to stop all active patches created by `start`
* BUGFIX: calling `MagicMock.reset_mock` wouldn't reset magic method mocks
* BUGFIX: calling `reset_mock` on a `MagicMock` created with autospec could
raise an exception
diff --git a/docs/patch.txt b/docs/patch.txt
index efbba4f..247fb08 100644
--- a/docs/patch.txt
+++ b/docs/patch.txt
@@ -491,8 +491,12 @@ method of a `TestCase`:
As an added bonus you no longer need to keep a reference to the `patcher`
object.
-In fact `start` and `stop` are just aliases for the context manager
-`__enter__` and `__exit__` methods.
+It is also possible to stop all patches which have been started by using
+`patch.stopall`.
+
+.. function:: patch.stopall
+
+ Stop all active patches.
TEST_PREFIX
diff --git a/mock.py b/mock.py
index 2b9bb30..5a539d9 100644
--- a/mock.py
+++ b/mock.py
@@ -1100,6 +1100,7 @@ def _is_started(patcher):
class _patch(object):
attribute_name = None
+ _active_patches = set()
def __init__(
self, getter, attribute, new, spec, create,
@@ -1378,8 +1379,18 @@ class _patch(object):
if _is_started(patcher):
patcher.__exit__(*exc_info)
- start = __enter__
- stop = __exit__
+
+ def start(self):
+ """Activate a patch, returning any created mock."""
+ result = self.__enter__()
+ self._active_patches.add(self)
+ return result
+
+
+ def stop(self):
+ """Stop an active patch."""
+ self._active_patches.discard(self)
+ return self.__exit__()
@@ -1673,9 +1684,16 @@ def _clear_dict(in_dict):
del in_dict[key]
+def _patch_stopall():
+ """Stop all active patches."""
+ for patch in list(_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 = (
diff --git a/tests/testpatch.py b/tests/testpatch.py
index 85939bb..1ebe671 100644
--- a/tests/testpatch.py
+++ b/tests/testpatch.py
@@ -1767,5 +1767,24 @@ class PatchTest(unittest2.TestCase):
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)
+
+
+
if __name__ == '__main__':
unittest2.main()