2
Copyright (c) 2007 Gustavo Niemeyer <gustavo@niemeyer.net>
4
Graceful platform for test doubles in Python (mocks, stubs, fakes, and dummies).
4
Graceful platform for test doubles in Python: mocks, stubs, fakes, and dummies.
6
Copyright (c) 2007-2010, Gustavo Niemeyer <gustavo@niemeyer.net>
10
Redistribution and use in source and binary forms, with or without
11
modification, are permitted provided that the following conditions are met:
13
* Redistributions of source code must retain the above copyright notice,
14
this list of conditions and the following disclaimer.
15
* Redistributions in binary form must reproduce the above copyright notice,
16
this list of conditions and the following disclaimer in the documentation
17
and/or other materials provided with the distribution.
18
* Neither the name of the copyright holder nor the names of its
19
contributors may be used to endorse or promote products derived from
20
this software without specific prior written permission.
22
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
26
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18
46
from sets import Set as set # pragma: nocover
21
__all__ = ["Mocker", "expect", "IS", "CONTAINS", "IN", "MATCH",
22
"ANY", "ARGS", "KWARGS"]
49
__all__ = ["Mocker", "Expect", "expect", "IS", "CONTAINS", "IN", "MATCH",
50
"ANY", "ARGS", "KWARGS", "MockerTestCase"]
25
53
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
26
__license__ = "PSF License"
27
__version__ = "0.10.1"
30
58
ERROR_PREFIX = "[Mocker] "
64
94
return self.__class__(self._mock, attr)
66
96
def __call__(self, *args, **kwargs):
67
getattr(self._mock.__mocker__, self._attr)(*args, **kwargs)
97
mocker = self.__mocker__
99
mocker = self._mock.__mocker__
100
getattr(mocker, self._attr)(*args, **kwargs)
105
"""Create an expect() "function" using the given Mocker instance.
107
This helper allows defining an expect() "function" which works even
108
in trickier cases such as:
110
expect = Expect(mymocker)
111
expect(iter(mock)).generate([1, 2, 3])
114
return type("Expect", (expect,), {"__mocker__": mocker})
71
117
# --------------------------------------------------------------------
72
118
# Extensions to Python's unittest.
88
134
a few additional helper methods.
93
137
def __init__(self, methodName="runTest"):
94
138
# So here is the trick: we take the real test method, wrap it on
95
139
# a function that do the job we have to do, and insert it in the
137
182
self.run = run_wrapper
139
184
self.mocker = Mocker()
185
self.expect = Expect(self.mocker)
141
187
self.__cleanup_funcs = []
142
188
self.__cleanup_paths = []
144
190
super(MockerTestCase, self).__init__(methodName)
192
def __call__(self, *args, **kwargs):
193
# This is necessary for Python 2.3 only, because it didn't use run(),
194
# which is supported above.
196
super(MockerTestCase, self).__call__(*args, **kwargs)
198
if sys.version_info < (2, 4):
146
201
def __cleanup(self):
147
202
for path in self.__cleanup_paths:
148
203
if os.path.isfile(path):
275
330
first_methods = dict(inspect.getmembers(first, inspect.ismethod))
276
331
second_methods = dict(inspect.getmembers(second, inspect.ismethod))
277
for name, first_method in first_methods.items():
332
for name, first_method in first_methods.iteritems():
278
333
first_argspec = inspect.getargspec(first_method)
279
334
first_formatted = inspect.formatargspec(*first_argspec)
292
347
(first.__name__, name, first_formatted,
293
348
second.__name__, name, second_formatted))
350
def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
352
Fail unless an exception of class excClass is thrown by callableObj
353
when invoked with arguments args and keyword arguments kwargs. If a
354
different type of exception is thrown, it will not be caught, and the
355
test case will be deemed to have suffered an error, exactly as for an
356
unexpected exception. It returns the exception instance if it matches
357
the given exception class.
360
result = callableObj(*args, **kwargs)
365
if hasattr(excClass, "__name__"):
366
excName = excClass.__name__
367
raise self.failureException(
368
"%s not raised (%r returned)" % (excName, result))
296
371
assertIs = failUnlessIs
297
372
assertIsNot = failIfIs
304
379
assertApproximates = failUnlessApproximates
305
380
assertNotApproximates = failIfApproximates
306
381
assertMethodsMatch = failUnlessMethodsMatch
382
assertRaises = failUnlessRaises
308
384
# The following are missing in Python < 2.4.
309
385
assertTrue = unittest.TestCase.failUnless
570
646
while import_stack:
571
647
module_path = ".".join(import_stack)
573
object = __import__(module_path, {}, {}, [""])
649
__import__(module_path)
574
650
except ImportError:
575
651
attr_stack.insert(0, import_stack.pop())
576
652
if not import_stack:
656
object = sys.modules[module_path]
580
657
for attr in attr_stack:
581
658
object = getattr(object, attr)
660
if isinstance(object, types.UnboundMethodType):
661
object = object.im_func
669
748
event.add_task(patcher)
670
749
mock = Mock(self, object=object, patcher=patcher,
671
750
passthrough=True, spec=spec)
672
object.__mocker_mock__ = mock
751
patcher.patch_attr(object, '__mocker_mock__', mock)
675
754
def act(self, path):
1052
1131
if self.__mocker__.is_recording() or self.__mocker_type__ is None:
1053
1132
return type(self)
1054
1133
return self.__mocker_type__
1134
if name == "__length_hint__":
1135
# This is used by Python 2.6+ to optimize the allocation
1136
# of arrays in certain cases. Pretend it doesn't exist.
1137
raise AttributeError("No __length_hint__ here!")
1055
1138
return self.__mocker_act__("getattr", (name,))
1057
1140
def __setattr__(self, name, value):
1920
2006
for referrer in gc.get_referrers(remove):
1921
2007
if (type(referrer) is dict and
1922
2008
referrer.get("__mocker_replace__", True)):
1923
for key, value in referrer.items():
2009
for key, value in list(referrer.iteritems()):
1924
2010
if value is remove:
1925
2011
referrer[key] = install
2020
2106
return unpatched(*action.args, **action.kwargs)
2021
2107
except AttributeError:
2108
type, value, traceback = sys.exc_info()
2022
2109
if action.kind == "getattr":
2023
2110
# The normal behavior of Python is to try __getattribute__,
2024
2111
# and if it raises AttributeError, try __getattr__. We've