Skip to content

Instantly share code, notes, and snippets.

@yamaneko1212
Created December 8, 2011 02:09
Show Gist options
  • Save yamaneko1212/1445774 to your computer and use it in GitHub Desktop.
Save yamaneko1212/1445774 to your computer and use it in GitHub Desktop.
モンキーパッチを管理する ref: http://qiita.com/items/1321
# -*- 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