Created
December 8, 2011 02:09
-
-
Save yamaneko1212/1445774 to your computer and use it in GitHub Desktop.
モンキーパッチを管理する ref: http://qiita.com/items/1321
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 | |
from unittest import TestCase | |
class PatchManager(object): | |
def __init__(self): | |
self._storage = {} | |
def attach(self, target, name, patch): | |
key = '%s.%s'%(target.__name__, name) | |
if self._storage.has_key(key): | |
raise ValueError('Patch for %s already exists.' % key) | |
self._storage[key] = { | |
'target': target, | |
'name': name, | |
'original': getattr(target, name) | |
} | |
setattr(target, name, patch) | |
return | |
def detach(self, target_name): | |
original = self._storage.get(target_name) | |
setattr(original['target'], original['name'], original['original']) | |
return | |
def detach_all(self): | |
for key in self._storage.keys(): | |
self.detach(key) | |
return | |
def __enter__(self): | |
return self | |
def __exit__(self, exc_type, exc_val, exc_tb): | |
self.detach_all() | |
if exc_type: | |
return False | |
return True | |
class TestPatchManager(TestCase): | |
def test_1(self): | |
"""Simple patching.""" | |
import datetime | |
def fake(): | |
return 'fake' | |
origin = datetime.datetime | |
mgr = PatchManager() | |
mgr.attach(datetime, 'datetime', fake) | |
self.assertNotEqual(datetime.datetime, origin) | |
self.assertEqual(datetime.datetime, fake) | |
mgr.detach('datetime.datetime') | |
self.assertEqual(datetime.datetime, origin) | |
return | |
def test_2(self): | |
"""Call detach all.""" | |
import datetime | |
def fake(): | |
return 'fake' | |
origin = datetime.datetime | |
mgr = PatchManager() | |
mgr.attach(datetime, 'datetime', fake) | |
self.assertNotEqual(datetime.datetime, origin) | |
self.assertEqual(datetime.datetime, fake) | |
mgr.detach_all() | |
self.assertEqual(datetime.datetime, origin) | |
return | |
def test_3(self): | |
"""Use with with context.""" | |
import datetime | |
def fake(): | |
return 'fake' | |
origin = datetime.datetime | |
with PatchManager() as mgr: | |
mgr.attach(datetime, 'datetime', fake) | |
self.assertNotEqual(datetime.datetime, origin) | |
self.assertEqual(datetime.datetime, fake) | |
self.assertEqual(datetime.datetime, origin) | |
return | |
def test_4(self): | |
"""If exceptions is occured in with context.""" | |
import datetime | |
def fake(): | |
return 'fake' | |
origin = datetime.datetime | |
with self.assertRaises(AssertionError): | |
with PatchManager() as mgr: | |
mgr.attach(datetime, 'datetime', fake) | |
self.assertNotEqual(datetime.datetime, origin) | |
self.assertEqual(datetime.datetime, fake) | |
assert False | |
self.assertEqual(datetime.datetime, origin) | |
return | |
def test_5(self): | |
"""Patched to the same obuject twice.""" | |
import datetime | |
def fake(): | |
return 'fake' | |
origin = datetime.datetime | |
with self.assertRaises(ValueError): | |
with PatchManager() as mgr: | |
mgr.attach(datetime, 'datetime', fake) | |
mgr.attach(datetime, 'datetime', fake) | |
assert False | |
self.assertEqual(datetime.datetime, origin) | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment