diff -r a15d65d8f269 Lib/unittest/case.py --- a/Lib/unittest/case.py Sat Mar 26 14:48:04 2011 +0100 +++ b/Lib/unittest/case.py Sat Mar 26 14:57:54 2011 -0300 @@ -267,6 +267,10 @@ _classSetupFailed = False + # List of patched objects + + _patched = [] + def __init__(self, methodName='runTest'): """Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does @@ -443,6 +447,8 @@ self._executeTestPart(self.tearDown, outcome) self.doCleanups() + self.unpatch_all() + if outcome.success: result.addSuccess(self) else: @@ -490,6 +496,17 @@ # even though we no longer us it internally return outcome.success + def patch(self, obj, attr, value): + """ Patch an object for the current test """ + self._patched.append((obj, attr, getattr(obj, attr))) + setattr(obj, attr, value) + + def unpatch_all(self): + """ Restore all patched objects to the previous state """ + for obj, attr, value in self._patched: + setattr(obj, attr, value) + self._patched = [] + def __call__(self, *args, **kwds): return self.run(*args, **kwds) diff -r a15d65d8f269 Lib/unittest/test/test_case.py --- a/Lib/unittest/test/test_case.py Sat Mar 26 14:48:04 2011 +0100 +++ b/Lib/unittest/test/test_case.py Sat Mar 26 14:57:54 2011 -0300 @@ -372,6 +372,25 @@ # ... and nothing should happen Foo().tearDown() + def test_patch(self): + + class Bar(object): + def foo(self): + return 42 + + class PatchTest(unittest.TestCase): + pass + + bar = Bar() + patch_test = PatchTest() + self.assertEqual(bar.foo(), 42) + + patch_test.patch(bar, 'foo', lambda: 7) + self.assertEqual(bar.foo(), 7) + + patch_test.unpatch_all() + self.assertEqual(bar.foo(), 42) + # "Return a string identifying the specific test case." # # Because of the vague nature of the docs, I'm not going to lock this