Created
January 31, 2012 21:28
-
-
Save yamaneko1212/1713029 to your computer and use it in GitHub Desktop.
メソッドとかの呼び出し回数をカウント/検証する. ref: http://qiita.com/items/1957
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
from unittest import TestCase | |
class CallCounter(object): | |
"""Check a numbe of time a callable is called.""" | |
def __new__(cls, *args, **kargs): | |
inst = super(CallCounter, cls).__new__(cls, *args, **kargs) | |
inst._patch_mgr = PatchManager() | |
inst._targets = {} | |
return inst | |
class FailedVerification(Exception): | |
pass | |
class CallCountManager(object): | |
def __init__ (self, target, name, expected): | |
self.__target = target | |
self.__name = name | |
self.__original = getattr(target, name) | |
self.__count = 0 | |
self.__expected = expected | |
def __call__(self, *args, **kargs): | |
self.__count += 1 | |
return self.__original(*args, **kargs) | |
def __verify(self): | |
if self.__count == self.__expected: | |
return | |
msg = '%s.%s should be called %d times but %d' % \ | |
(self.__target.__name__, self.__name, self.__expected, | |
self.__count,) | |
raise CallCounter.FailedVerification(msg) | |
def ensure(self, target, name, count): | |
counter = self.CallCountManager(target, name, count) | |
key = '%s.%s'%(target.__name__, name) | |
self._targets[key] = counter | |
self._patch_mgr.attach(target, name, counter) | |
return | |
def verify(self): | |
for key, counter in self._targets.iteritems(): | |
counter._CallCountManager__verify() | |
return | |
def end(self): | |
self._patch_mgr.detach_all() | |
return | |
def __enter__(self): | |
return self | |
def __exit__(self, exc_type, exc_val, exc_tb): | |
self.end() | |
if exc_type: | |
return False | |
return True | |
class TestCallCounter(TestCase): | |
"""Test for test.CallCounter.""" | |
def test_1(self): | |
"""Call it simply.""" | |
c = CallCounter() | |
import datetime | |
original = datetime.datetime | |
c.ensure(datetime, 'datetime', 1) | |
self.assert_(isinstance(datetime.datetime, | |
CallCounter.CallCountManager)) | |
self.assertNotEqual(datetime.datetime, original) | |
# Call it first. | |
datetime.datetime(year=2011, month=3, day=4) | |
c.verify() | |
# Call it second. | |
datetime.datetime(year=2011, month=3, day=4) | |
with self.assertRaises(CallCounter.FailedVerification): | |
c.verify() | |
# Verify a clearance. | |
c.end() | |
self.assertEqual(datetime.datetime, original) | |
return | |
def test_2(self): | |
"""Call it simply.""" | |
c = CallCounter() | |
import datetime | |
original = datetime.datetime | |
c.ensure(datetime, 'datetime', 0) | |
self.assertNotEqual(datetime.datetime, original) | |
# Call it and verify. | |
datetime.datetime(year=2011, month=3, day=4) | |
with self.assertRaises(CallCounter.FailedVerification): | |
c.verify() | |
c.end() | |
self.assertEqual(datetime.datetime, original) | |
return | |
def test_3(self): | |
"""Use it with `with statement`.""" | |
import datetime | |
original = datetime.datetime | |
with self.assertRaises(CallCounter.FailedVerification): | |
with CallCounter() as c: | |
c.ensure(datetime, 'datetime', 0) | |
self.assertNotEqual(datetime.datetime, original) | |
# Call it and verify. | |
datetime.datetime(year=2011, month=3, day=4) | |
c.verify() | |
self.assertEqual(datetime.datetime, original) | |
return | |
def test_4(self): | |
"""Exception is happend in with statement.""" | |
import datetime | |
original = datetime.datetime | |
with self.assertRaises(AssertionError): | |
with CallCounter() as c: | |
c.ensure(datetime, 'datetime', 0) | |
self.assertNotEqual(datetime.datetime, original) | |
# Call it and verify. | |
datetime.datetime(year=2011, month=3, day=4) | |
raise AssertionError() | |
self.assertEqual(datetime.datetime, original) | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment