summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/conf.py2
-rw-r--r--extendmock.py16
-rw-r--r--mock.py1485
-rwxr-xr-xsetup.py4
-rw-r--r--tests/__init__.py7
-rw-r--r--tests/support.py4
-rw-r--r--tests/support_with.py8
-rw-r--r--tests/testmagicmethods.py535
-rw-r--r--tests/testmock.py613
-rw-r--r--tests/testmocksignature.py48
-rw-r--r--tests/testpatch.py1205
-rw-r--r--tests/testsentinel.py61
-rw-r--r--tests/testwith.py35
13 files changed, 2008 insertions, 2015 deletions
diff --git a/docs/conf.py b/docs/conf.py
index b6c3838..33616e5 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -176,4 +176,4 @@ latex_documents = [
#latex_appendices = []
# If false, no module index is generated.
-latex_use_modindex = False
+latex_use_modindex = False \ No newline at end of file
diff --git a/extendmock.py b/extendmock.py
index 5728631..07f0ec0 100644
--- a/extendmock.py
+++ b/extendmock.py
@@ -22,14 +22,14 @@ to mock instances in the same way you mock other attributes::
mock = Mock()
mock.__repr__ = lambda self: 'some string'
-Note that functions (or callable objects like a Mock instance) that are used for
+Note that functions (or callable objects like a Mock instance) that are used for
magic methods must take self as the first argument.
-
+
The only unsupported magic methods (that I'm aware of) are:
* Used by Mock: __init__, __new__, __getattr__, __setattr__, __delattr__, __call__
* Rare: __dir__,
-* Can cause bad interactions with other functionality:
+* Can cause bad interactions with other functionality:
- __reversed__, __missing__, __del__, __unicode__, __getattribute__
- __get__, __set__, __delete__
@@ -50,12 +50,12 @@ DELEGATE = MISSING = object()
def getsignature(func):
assert inspect.ismethod(func) or inspect.isfunction(func)
regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
-
+
# instance methods need to lose the self argument
im_self = getattr(func, 'im_self', None)
if im_self is not None:
regargs = regargs[1:]
-
+
argnames = list(regargs)
if varargs:
argnames.append(varargs)
@@ -69,7 +69,7 @@ def getsignature(func):
def mocksignature(func, mock):
signature = getsignature(func)
src = "lambda %(signature)s: _mock_(%(signature)s)" % {'signature': signature}
-
+
funcopy = eval(src, dict(_mock_=mock))
funcopy.__name__ = func.__name__
funcopy.__doc__ = func.__doc__
@@ -93,7 +93,7 @@ class MagicMock(Mock):
method = _all_magics[name]
setattr(self.__class__, name, method)
return Mock.__setattr__(self, name, value)
-
+
def __delattr__(self, name):
if name in _all_magics and name in self.__class__.__dict__:
delattr(self.__class__, name)
@@ -123,7 +123,7 @@ def get_method(name):
_all_magics = {}
for method in sum([methods.split() for methods in [magic_methods, numerics, inplace, right]], []):
- name = '__%s__' % method
+ name = '__%s__' % method
_all_magics[name] = get_method(name)
import mock
diff --git a/mock.py b/mock.py
index 38f055b..ce4bb00 100644
--- a/mock.py
+++ b/mock.py
@@ -1,743 +1,742 @@
-# mock.py
-# Test tools for mocking and patching.
-# Copyright (C) 2007-2010 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-
-# mock 0.7.0
-# http://www.voidspace.org.uk/python/mock/
-
-# Released subject to the BSD License
-# Please see http://www.voidspace.org.uk/python/license.shtml
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# Comments, suggestions and bug reports welcome.
-
-
-__all__ = (
- 'Mock',
- 'MagicMock',
- 'mocksignature',
- 'patch',
- 'patch_object',
- 'sentinel',
- 'DEFAULT'
-)
-
-__version__ = '0.7.0'
-
-import sys
-import warnings
-
-try:
- import inspect
-except ImportError:
- # for alternative platforms that
- # may not have inspect
- inspect = None
-
-try:
- BaseException
-except NameError:
- # Python 2.4 compatibility
- BaseException = Exception
-
-try:
- from functools import wraps
-except ImportError:
- # Python 2.4 compatibility
- def wraps(original):
- def inner(f):
- f.__name__ = original.__name__
- return f
- return inner
-
-try:
- unicode
-except NameError:
- # Python 3
- basestring = unicode = str
-
-try:
- long
-except NameError:
- # Python 3
- long = int
-
-inPy3k = sys.version_info[0] == 3
-
-
-# getsignature and mocksignature heavily "inspired" by
-# the decorator module: http://pypi.python.org/pypi/decorator/
-# by Michele Simionato
-
-def _getsignature(func, skipfirst):
- if inspect is None:
- raise ImportError('inspect module not available')
- assert inspect.ismethod(func) or inspect.isfunction(func)
- regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
-
- # instance methods need to lose the self argument
- if not inPy3k:
- im_self = getattr(func, 'im_self', None)
- else:
- im_self = getattr(func, '__self__', None)
- if im_self is not None:
- regargs = regargs[1:]
-
- assert '_mock_' not in regargs, ("_mock_ is a reserved argument name, can't mock signatures using _mock_")
- if skipfirst:
- regargs = regargs[1:]
- signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults, formatvalue=lambda value: "")
- return signature[1:-1]
-
-
-def _copy_func_details(func, funcopy):
- funcopy.__name__ = func.__name__
- funcopy.__doc__ = func.__doc__
- funcopy.__dict__.update(func.__dict__)
- funcopy.__module__ = func.__module__
- if not inPy3k:
- funcopy.func_defaults = func.func_defaults
- else:
- funcopy.__defaults__ = func.__defaults__
- funcopy.__kwdefaults__ = func.__kwdefaults__
-
-
-def mocksignature(func, mock=None, skipfirst=False):
- """
- mocksignature(func, mock=None, skipfirst=False)
-
- Create a new function with the same signature as `func` that delegates
- to `mock`. If `skipfirst` is True the first argument is skipped, useful
- for methods where `self` needs to be omitted from the new function.
-
- If you don't pass in a `mock` then one will be created for you.
-
- The mock is set as the `mock` attribute of the returned function for easy
- access.
- """
- if mock is None:
- mock = Mock()
- signature = _getsignature(func, skipfirst)
- src = "lambda %(signature)s: _mock_(%(signature)s)" % {'signature': signature}
-
- funcopy = eval(src, dict(_mock_=mock))
- _copy_func_details(func, funcopy)
- funcopy.mock = mock
- return funcopy
-
-
-def _is_magic(name):
- return '__%s__' % name[2:-2] == name
-
-
-class SentinelObject(object):
- "A unique, named, sentinel object."
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return '<SentinelObject "%s">' % self.name
-
-
-class Sentinel(object):
- """Access attributes to return a named object, usable as a sentinel."""
- def __init__(self):
- self._sentinels = {}
-
- def __getattr__(self, name):
- if name == '__bases__':
- # Without this help(mock) raises an exception
- raise AttributeError
- return self._sentinels.setdefault(name, SentinelObject(name))
-
-
-sentinel = Sentinel()
-
-DEFAULT = sentinel.DEFAULT
-
-class OldStyleClass:
- pass
-ClassType = type(OldStyleClass)
-
-def _copy(value):
- if type(value) in (dict, list, tuple, set):
- return type(value)(value)
- return value
-
-
-if inPy3k:
- class_types = type
-else:
- class_types = (type, ClassType)
-
-
-class Mock(object):
- """
- Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None)
-
- Create a new ``Mock`` object. ``Mock`` takes several optional arguments
- that specify the behaviour of the Mock object:
-
- * ``spec``: This can be either a list of strings or an existing object (a
- class or instance) that acts as the specification for the mock object. If
- you pass in an object then a list of strings is formed by calling dir on
- the object (excluding unsupported magic attributes and methods). Accessing
- any attribute not in this list will raise an ``AttributeError``.
-
- * ``side_effect``: A function to be called whenever the Mock is called. See
- the :attr:`Mock.side_effect` attribute. Useful for raising exceptions or
- dynamically changing return values. The function is called with the same
- arguments as the mock, and unless it returns :data:`DEFAULT`, the return
- value of this function is used as the return value.
-
- Alternatively ``side_effect`` can be an exception class or instance. In
- this case the exception will be raised when the mock is called.
-
- * ``return_value``: The value returned when the mock is called. By default
- this is a new Mock (created on first access). See the
- :attr:`Mock.return_value` attribute.
-
- * ``wraps``: Item for the mock object to wrap. If ``wraps`` is not None
- then calling the Mock will pass the call through to the wrapped object
- (returning the real result and ignoring ``return_value``). Attribute
- access on the mock will return a Mock object that wraps the corresponding
- attribute of the wrapped object (so attempting to access an attribute that
- doesn't exist will raise an ``AttributeError``).
-
- If the mock has an explicit ``return_value`` set then calls are not passed
- to the wrapped object and the ``return_value`` is returned instead.
- """
- def __new__(cls, *args, **kw):
- class Mock(cls):
- # every instance has its own class
- # so we can create magic methods on the
- # class without stomping on other mocks
- pass
- return object.__new__(Mock)
-
- def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
- name=None, parent=None, wraps=None):
- self._parent = parent
- self._name = name
- if spec is not None and not isinstance(spec, list):
- spec = [member for member in dir(spec) if not _is_magic(member)]
-
- self._methods = spec
- self._children = {}
- self._return_value = return_value
- self.side_effect = side_effect
- self._wraps = wraps
-
- self.reset_mock()
-
-
- def reset_mock(self):
- "Restore the mock object to its initial state."
- self.called = False
- self.call_args = None
- self.call_count = 0
- self.call_args_list = []
- self.method_calls = []
- for child in self._children.values():
- child.reset_mock()
- if isinstance(self._return_value, Mock):
- self._return_value.reset_mock()
-
-
- def __get_return_value(self):
- if self._return_value is DEFAULT:
- self._return_value = Mock()
- return self._return_value
-
- def __set_return_value(self, value):
- self._return_value = value
-
- __return_value_doc = "The value to be returned when the mock is called."
-
- return_value = property(__get_return_value, __set_return_value,
- __return_value_doc)
-
-
- def __call__(self, *args, **kwargs):
- self.called = True
- self.call_count += 1
- self.call_args = callargs((args, kwargs))
- self.call_args_list.append(callargs((args, kwargs)))
-
- parent = self._parent
- name = self._name
- while parent is not None:
- parent.method_calls.append(callargs((name, args, kwargs)))
- if parent._parent is None:
- break
- name = parent._name + '.' + name
- parent = parent._parent
-
- ret_val = DEFAULT
- if self.side_effect is not None:
- if (isinstance(self.side_effect, BaseException) or
- isinstance(self.side_effect, class_types) and
- issubclass(self.side_effect, BaseException)):
- raise self.side_effect
-
- ret_val = self.side_effect(*args, **kwargs)
- if ret_val is DEFAULT:
- ret_val = self.return_value
-
- if self._wraps is not None and self._return_value is DEFAULT:
- return self._wraps(*args, **kwargs)
- if ret_val is DEFAULT:
- ret_val = self.return_value
- return ret_val
-
-
- def __getattr__(self, name):
- if self._methods is not None:
- if name not in self._methods:
- raise AttributeError("Mock object has no attribute '%s'" % name)
- elif _is_magic(name):
- raise AttributeError(name)
-
- if name not in self._children:
- wraps = None
- if self._wraps is not None:
- wraps = getattr(self._wraps, name)
- self._children[name] = Mock(parent=self, name=name, wraps=wraps)
-
- return self._children[name]
-
- def __setattr__(self, name, value):
- if name in _all_magics:
- if not isinstance(value, Mock):
- setattr(self.__class__, name, get_method(name, value))
- original = value
- real = lambda *args, **kw: original(self, *args, **kw)
- value = mocksignature(value, real, skipfirst=True)
- else:
- setattr(self.__class__, name, value)
- return object.__setattr__(self, name, value)
-
- def __delattr__(self, name):
- if name in _all_magics and name in self.__class__.__dict__:
- delattr(self.__class__, name)
- return object.__delattr__(self, name)
-
- def assert_called_with(self, *args, **kwargs):
- """
- assert that the mock was called with the specified arguments.
-
- Raises an AttributeError if the args and keyword args passed in are
- different to the last call to the mock.
- """
- assert self.call_args == (args, kwargs), 'Expected: %s\nCalled with: %s' % ((args, kwargs), self.call_args)
-
-
-class callargs(tuple):
- """
- A tuple for holding the results of a call to a mock, either in the form
- `(args, kwargs)` or `(name, args, kwargs)`.
-
- If args or kwargs are empty then a callargs tuple will compare equal to
- a tuple without those values. This makes comparisons less verbose::
-
- callargs('name', (), {}) == ('name',)
- callargs('name', (1,), {}) == ('name', (1,))
- callargs((), {'a': 'b'}) == ({'a': 'b'},)
- """
- def __eq__(self, other):
- if len(self) == 3:
- if other[0] != self[0]:
- return False
- args_kwargs = self[1:]
- other_args_kwargs = other[1:]
- else:
- args_kwargs = tuple(self)
- other_args_kwargs = other
-
- if len(other_args_kwargs) == 0:
- other_args, other_kwargs = (), {}
- elif len(other_args_kwargs) == 1:
- if isinstance(other_args_kwargs[0], tuple):
- other_args = other_args_kwargs[0]
- other_kwargs = {}
- else:
- other_args = ()
- other_kwargs = other_args_kwargs[0]
- else:
- other_args, other_kwargs = other_args_kwargs
-
- return tuple(args_kwargs) == (other_args, other_kwargs)
-
-def _dot_lookup(thing, comp, import_path):
- try:
- return getattr(thing, comp)
- except AttributeError:
- __import__(import_path)
- return getattr(thing, comp)
-
-
-def _importer(target):
- components = target.split('.')
- import_path = components.pop(0)
- thing = __import__(import_path)
-
- for comp in components:
- import_path += ".%s" % comp
- thing = _dot_lookup(thing, comp, import_path)
- return thing
-
-
-class _patch(object):
- def __init__(self, target, attribute, new, spec, create, mocksignature):
- self.target = target
- self.attribute = attribute
- self.new = new
- self.spec = spec
- self.create = create
- self.has_local = False
- self.mocksignature = mocksignature
-
-
- def copy(self):
- return _patch(self.target, self.attribute, self.new,
- self.spec, self.create, self.mocksignature)
-
-
- def __call__(self, func):
- if isinstance(func, class_types):
- return self.decorate_class(func)
- else:
- return self.decorate_callable(func)
-
- def decorate_class(self, klass):
- for attr in dir(klass):
- attr_value = getattr(klass, attr)
- if attr.startswith("test") and hasattr(attr_value, "__call__"):
- setattr(klass, attr, self.copy()(attr_value))
- return klass
-
- def decorate_callable(self, func):
- if hasattr(func, 'patchings'):
- func.patchings.append(self)
- return func
-
- @wraps(func)
- def patched(*args, **keywargs):
- # don't use a with here (backwards compatability with 2.5)
- extra_args = []
- for patching in patched.patchings:
- arg = patching.__enter__()
- if patching.new is DEFAULT:
- extra_args.append(arg)
- args += tuple(extra_args)
- try:
- return func(*args, **keywargs)
- finally:
- for patching in reversed(getattr(patched, 'patchings', [])):
- patching.__exit__()
-
- patched.patchings = [self]
- if hasattr(func, 'func_code'):
- # not in Python 3
- patched.compat_co_firstlineno = getattr(func, "compat_co_firstlineno",
- func.func_code.co_firstlineno)
- return patched
-
-
- def get_original(self):
- target = self.target
- name = self.attribute
- create = self.create
-
- original = DEFAULT
- if _has_local_attr(target, name):
- try:
- original = target.__dict__[name]
- except AttributeError:
- # for instances of classes with slots, they have no __dict__
- original = getattr(target, name)
- elif not create and not hasattr(target, name):
- raise AttributeError("%s does not have the attribute %r" % (target, name))
- return original
-
-
- def __enter__(self):
- new, spec, = self.new, self.spec
- original = self.get_original()
- if new is DEFAULT:
- # XXXX what if original is DEFAULT - shouldn't use it as a spec
- inherit = False
- if spec == True:
- # set spec to the object we are replacing
- spec = original
- if isinstance(spec, class_types):
- inherit = True
- new = Mock(spec=spec)
- if inherit:
- new.return_value = Mock(spec=spec)
- new_attr = new
- if self.mocksignature:
- new_attr = mocksignature(original, new)
-
- self.temp_original = original
- setattr(self.target, self.attribute, new_attr)
- return new
-
-
- def __exit__(self, *_):
- if self.temp_original is not DEFAULT:
- setattr(self.target, self.attribute, self.temp_original)
- else:
- delattr(self.target, self.attribute)
- del self.temp_original
-
-
-def _patch_object(target, attribute, new=DEFAULT, spec=None, create=False, mocksignature=False):
- """
- patch.object(target, attribute, new=DEFAULT, spec=None, create=False, mocksignature=False)
-
- patch the named member (`attribute`) on an object (`target`) with a mock
- object.
-
- Arguments new, spec, create and mocksignature have the same meaning as for
- patch.
- """
- return _patch(target, attribute, new, spec, create, mocksignature)
-
-def patch_object(*args, **kwargs):
- "A deprecated form of patch.object(...)"
- warnings.warn(('Please use patch.object instead.'), DeprecationWarning, 2)
- return _patch_object(*args, **kwargs)
-
-def patch(target, new=DEFAULT, spec=None, create=False, mocksignature=False):
- """
- patch(target, new=DEFAULT, spec=None, create=False, mocksignature=False)
-
- ``patch`` acts as a function decorator or a context manager. Inside the body
- of the function or with statement, the ``target`` (specified in the form
- 'PackageName.ModuleName.ClassName') is patched with a ``new`` object. When the
- function/with statement exits the patch is undone.
-
- The target is imported and the specified attribute patched with the new object
- - so it must be importable from the environment you are calling the decorator
- from.
-
- If ``new`` is omitted, then a new ``Mock`` is created and passed in as an
- extra argument to the decorated function.
-
- The ``spec`` keyword argument is passed to the ``Mock`` if patch is creating
- one for you.
-
- In addition you can pass ``spec=True``, which causes patch to pass in the
- object being mocked as the spec object.
-
- If ``mocksignature`` is True then the patch will be done with a function
- created by mocking the one being replaced.
-
- patch.dict(...) and patch.object(...) are available for alternate use-cases.
- """
- try:
- target, attribute = target.rsplit('.', 1)
- except (TypeError, ValueError):
- raise TypeError("Need a valid target to patch. You supplied: %r" % (target,))
- target = _importer(target)
- return _patch(target, attribute, new, spec, create, mocksignature)
-
-class _patch_dict(object):
- """
- patch.dict(in_dict, values=(), clear=False)
-
- Patch a dictionary and restore the dictionary to its original state after
- the test.
-
- `in_dict` can be a dictionary or a mapping like container. If it is a
- mapping then it must at least support getting, setting and deleting items
- plus iterating over keys.
-
- `in_dict` can also be a string specifying the name of the dictionary, which
- will then be fetched by importing it.
-
- `values` can be a dictionary of values to set in the dictionary. `values`
- can also be an iterable of ``(key, value)`` pairs.
-
- If `clear` is True then the dictionary will be cleared before the new
- values are set.
- """
-
- def __init__(self, in_dict, values=(), clear=False):
- if isinstance(in_dict, basestring):
- in_dict = _importer(in_dict)
- self.in_dict = in_dict
- # support any argument supported by dict(...) constructor
- self.values = dict(values)
- self.clear = clear
- self._original = None
-
- def __call__(self, f):
- @wraps(f)
- def _inner(*args, **kw):
- self._patch_dict()
- try:
- return f(*args, **kw)
- finally:
- self._unpatch_dict()
-
- return _inner
-
- def __enter__(self):
- self._patch_dict()
-
- def _patch_dict(self):
- values = self.values
- in_dict = self.in_dict
- clear = self.clear
-
- try:
- original = in_dict.copy()
- except AttributeError:
- # dict like object with no copy method
- # must support iteration over keys
- original = {}
- for key in in_dict:
- original[key] = in_dict[key]
- self._original = original
-
- if clear:
- _clear_dict(in_dict)
-
- try:
- in_dict.update(values)
- except AttributeError:
- # dict like object with no update method
- for key in values:
- in_dict[key] = values[key]
-
- def _unpatch_dict(self):
- in_dict = self.in_dict
- original = self._original
-
- _clear_dict(in_dict)
-
- try:
- in_dict.update(original)
- except AttributeError:
- for key in original:
- in_dict[key] = original[key]
-
-
- def __exit__(self, *args):
- self._unpatch_dict()
- return False
-
-
-def _clear_dict(in_dict):
- try:
- in_dict.clear()
- except AttributeError:
- keys = list(in_dict)
- for key in keys:
- del in_dict[key]
-
-
-patch.object = _patch_object
-patch.dict = _patch_dict
-
-def _has_local_attr(obj, name):
- try:
- return name in vars(obj)
- except TypeError:
- # objects without a __dict__
- return hasattr(obj, name)
-
-
-magic_methods = (
- "lt le gt ge eq ne "
- "getitem setitem delitem "
- "len contains iter "
- "hash repr str "
- "enter exit "
- "divmod neg pos abs invert "
- "complex int float index "
-)
-
-numerics = "add sub mul div truediv floordiv mod lshift rshift and xor or pow "
-inplace = ' '.join('i%s' % n for n in numerics.split())
-right = ' '.join('r%s' % n for n in numerics.split())
-extra = ''
-if inPy3k:
- extra = 'bool next '
-else:
- extra = 'unicode long nonzero oct hex '
-# __truediv__ and __rtruediv__ not available in Python 3 either
-
-# not including __prepare__, __instancecheck__, __subclasscheck__
-# (as they are metaclass methods)
-# __del__ is not supported at all as it causes problems if it exists
-
-_non_defaults = set('__%s__' % method for method in [
- 'cmp', 'getslice', 'setslice', 'coerce', 'subclasses',
- 'dir', 'format', 'get', 'set', 'delete', 'reversed',
- 'missing',
-])
-
-def get_method(name, func):
- def method(self, *args, **kw):
- return func(self, *args, **kw)
- method.__name__ = name
- return method
-
-_magics = set('__%s__' % method for method in ' '.join([magic_methods, numerics, inplace, right, extra]).split())
-
-_all_magics = _magics | _non_defaults
-
-
-_side_effects = {
- '__hash__': lambda self: object.__hash__(self),
- '__repr__': lambda self: object.__repr__(self),
- '__str__': lambda self: object.__str__(self),
- '__unicode__': lambda self: unicode(object.__str__(self)),
-}
-
-_return_values = {
- '__int__': 0,
- '__contains__': False,
- '__len__': 0,
- '__iter__': iter([]),
- '__exit__': False,
- '__complex__': 0j,
- '__float__': 0.0,
- '__bool__': True,
- '__nonzero__': True,
- '__oct__': '0',
- '__hex__': '0x0',
- '__long__': long(0),
- '__index__': 0,
-}
-
-def _set_return_value(mock, method, name):
- if name in _side_effects:
- func = _side_effects[name]
- def wrap(*args, **kw):
- if method._return_value is DEFAULT:
- return func(mock)
- return method._return_value
- method.side_effect = wrap
- elif name in _return_values:
- method.return_value = _return_values[name]
-
-
-class MagicMock(Mock):
- """
- MagicMock is a subclass of :Mock with default implementations
- of most of the magic methods. You can use MagicMock without having to
- configure the magic methods yourself.
- """
- def __init__(self, *args, **kw):
- Mock.__init__(self, *args, **kw)
- for entry in _magics:
- # could specify parent?
- m = Mock()
- setattr(self, entry, m)
- _set_return_value(self, m, entry)
-
+# mock.py
+# Test tools for mocking and patching.
+# Copyright (C) 2007-2010 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+
+# mock 0.7.0
+# http://www.voidspace.org.uk/python/mock/
+
+# Released subject to the BSD License
+# Please see http://www.voidspace.org.uk/python/license.shtml
+
+# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
+# Comments, suggestions and bug reports welcome.
+
+
+__all__ = (
+ 'Mock',
+ 'MagicMock',
+ 'mocksignature',
+ 'patch',
+ 'patch_object',
+ 'sentinel',
+ 'DEFAULT'
+)
+
+__version__ = '0.7.0'
+
+import sys
+import warnings
+
+try:
+ import inspect
+except ImportError:
+ # for alternative platforms that
+ # may not have inspect
+ inspect = None
+
+try:
+ BaseException
+except NameError:
+ # Python 2.4 compatibility
+ BaseException = Exception
+
+try:
+ from functools import wraps
+except ImportError:
+ # Python 2.4 compatibility
+ def wraps(original):
+ def inner(f):
+ f.__name__ = original.__name__
+ return f
+ return inner
+
+try:
+ unicode
+except NameError:
+ # Python 3
+ basestring = unicode = str
+
+try:
+ long
+except NameError:
+ # Python 3
+ long = int
+
+inPy3k = sys.version_info[0] == 3
+
+
+# getsignature and mocksignature heavily "inspired" by
+# the decorator module: http://pypi.python.org/pypi/decorator/
+# by Michele Simionato
+
+def _getsignature(func, skipfirst):
+ if inspect is None:
+ raise ImportError('inspect module not available')
+ assert inspect.ismethod(func) or inspect.isfunction(func)
+ regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
+
+ # instance methods need to lose the self argument
+ if not inPy3k:
+ im_self = getattr(func, 'im_self', None)
+ else:
+ im_self = getattr(func, '__self__', None)
+ if im_self is not None:
+ regargs = regargs[1:]
+
+ assert '_mock_' not in regargs, ("_mock_ is a reserved argument name, can't mock signatures using _mock_")
+ if skipfirst:
+ regargs = regargs[1:]
+ signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults, formatvalue=lambda value: "")
+ return signature[1:-1]
+
+
+def _copy_func_details(func, funcopy):
+ funcopy.__name__ = func.__name__
+ funcopy.__doc__ = func.__doc__
+ funcopy.__dict__.update(func.__dict__)
+ funcopy.__module__ = func.__module__
+ if not inPy3k:
+ funcopy.func_defaults = func.func_defaults
+ else:
+ funcopy.__defaults__ = func.__defaults__
+ funcopy.__kwdefaults__ = func.__kwdefaults__
+
+
+def mocksignature(func, mock=None, skipfirst=False):
+ """
+ mocksignature(func, mock=None, skipfirst=False)
+
+ Create a new function with the same signature as `func` that delegates
+ to `mock`. If `skipfirst` is True the first argument is skipped, useful
+ for methods where `self` needs to be omitted from the new function.
+
+ If you don't pass in a `mock` then one will be created for you.
+
+ The mock is set as the `mock` attribute of the returned function for easy
+ access.
+ """
+ if mock is None:
+ mock = Mock()
+ signature = _getsignature(func, skipfirst)
+ src = "lambda %(signature)s: _mock_(%(signature)s)" % {'signature': signature}
+
+ funcopy = eval(src, dict(_mock_=mock))
+ _copy_func_details(func, funcopy)
+ funcopy.mock = mock
+ return funcopy
+
+
+def _is_magic(name):
+ return '__%s__' % name[2:-2] == name
+
+
+class SentinelObject(object):
+ "A unique, named, sentinel object."
+ def __init__(self, name):
+ self.name = name
+
+ def __repr__(self):
+ return '<SentinelObject "%s">' % self.name
+
+
+class Sentinel(object):
+ """Access attributes to return a named object, usable as a sentinel."""
+ def __init__(self):
+ self._sentinels = {}
+
+ def __getattr__(self, name):
+ if name == '__bases__':
+ # Without this help(mock) raises an exception
+ raise AttributeError
+ return self._sentinels.setdefault(name, SentinelObject(name))
+
+
+sentinel = Sentinel()
+
+DEFAULT = sentinel.DEFAULT
+
+class OldStyleClass:
+ pass
+ClassType = type(OldStyleClass)
+
+def _copy(value):
+ if type(value) in (dict, list, tuple, set):
+ return type(value)(value)
+ return value
+
+
+if inPy3k:
+ class_types = type
+else:
+ class_types = (type, ClassType)
+
+
+class Mock(object):
+ """
+ Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None)
+
+ Create a new ``Mock`` object. ``Mock`` takes several optional arguments
+ that specify the behaviour of the Mock object:
+
+ * ``spec``: This can be either a list of strings or an existing object (a
+ class or instance) that acts as the specification for the mock object. If
+ you pass in an object then a list of strings is formed by calling dir on
+ the object (excluding unsupported magic attributes and methods). Accessing
+ any attribute not in this list will raise an ``AttributeError``.
+
+ * ``side_effect``: A function to be called whenever the Mock is called. See
+ the :attr:`Mock.side_effect` attribute. Useful for raising exceptions or
+ dynamically changing return values. The function is called with the same
+ arguments as the mock, and unless it returns :data:`DEFAULT`, the return
+ value of this function is used as the return value.
+
+ Alternatively ``side_effect`` can be an exception class or instance. In
+ this case the exception will be raised when the mock is called.
+
+ * ``return_value``: The value returned when the mock is called. By default
+ this is a new Mock (created on first access). See the
+ :attr:`Mock.return_value` attribute.
+
+ * ``wraps``: Item for the mock object to wrap. If ``wraps`` is not None
+ then calling the Mock will pass the call through to the wrapped object
+ (returning the real result and ignoring ``return_value``). Attribute
+ access on the mock will return a Mock object that wraps the corresponding
+ attribute of the wrapped object (so attempting to access an attribute that
+ doesn't exist will raise an ``AttributeError``).
+
+ If the mock has an explicit ``return_value`` set then calls are not passed
+ to the wrapped object and the ``return_value`` is returned instead.
+ """
+ def __new__(cls, *args, **kw):
+ class Mock(cls):
+ # every instance has its own class
+ # so we can create magic methods on the
+ # class without stomping on other mocks
+ pass
+ return object.__new__(Mock)
+
+ def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
+ name=None, parent=None, wraps=None):
+ self._parent = parent
+ self._name = name
+ if spec is not None and not isinstance(spec, list):
+ spec = [member for member in dir(spec) if not _is_magic(member)]
+
+ self._methods = spec
+ self._children = {}
+ self._return_value = return_value
+ self.side_effect = side_effect
+ self._wraps = wraps
+
+ self.reset_mock()
+
+
+ def reset_mock(self):
+ "Restore the mock object to its initial state."
+ self.called = False
+ self.call_args = None
+ self.call_count = 0
+ self.call_args_list = []
+ self.method_calls = []
+ for child in self._children.values():
+ child.reset_mock()
+ if isinstance(self._return_value, Mock):
+ self._return_value.reset_mock()
+
+
+ def __get_return_value(self):
+ if self._return_value is DEFAULT:
+ self._return_value = Mock()
+ return self._return_value
+
+ def __set_return_value(self, value):
+ self._return_value = value
+
+ __return_value_doc = "The value to be returned when the mock is called."
+
+ return_value = property(__get_return_value, __set_return_value,
+ __return_value_doc)
+
+
+ def __call__(self, *args, **kwargs):
+ self.called = True
+ self.call_count += 1
+ self.call_args = callargs((args, kwargs))
+ self.call_args_list.append(callargs((args, kwargs)))
+
+ parent = self._parent
+ name = self._name
+ while parent is not None:
+ parent.method_calls.append(callargs((name, args, kwargs)))
+ if parent._parent is None:
+ break
+ name = parent._name + '.' + name
+ parent = parent._parent
+
+ ret_val = DEFAULT
+ if self.side_effect is not None:
+ if (isinstance(self.side_effect, BaseException) or
+ isinstance(self.side_effect, class_types) and
+ issubclass(self.side_effect, BaseException)):
+ raise self.side_effect
+
+ ret_val = self.side_effect(*args, **kwargs)
+ if ret_val is DEFAULT:
+ ret_val = self.return_value
+
+ if self._wraps is not None and self._return_value is DEFAULT:
+ return self._wraps(*args, **kwargs)
+ if ret_val is DEFAULT:
+ ret_val = self.return_value
+ return ret_val
+
+
+ def __getattr__(self, name):
+ if self._methods is not None:
+ if name not in self._methods:
+ raise AttributeError("Mock object has no attribute '%s'" % name)
+ elif _is_magic(name):
+ raise AttributeError(name)
+
+ if name not in self._children:
+ wraps = None
+ if self._wraps is not None:
+ wraps = getattr(self._wraps, name)
+ self._children[name] = Mock(parent=self, name=name, wraps=wraps)
+
+ return self._children[name]
+
+ def __setattr__(self, name, value):
+ if name in _all_magics:
+ if not isinstance(value, Mock):
+ setattr(self.__class__, name, get_method(name, value))
+ original = value
+ real = lambda *args, **kw: original(self, *args, **kw)
+ value = mocksignature(value, real, skipfirst=True)
+ else:
+ setattr(self.__class__, name, value)
+ return object.__setattr__(self, name, value)
+
+ def __delattr__(self, name):
+ if name in _all_magics and name in self.__class__.__dict__:
+ delattr(self.__class__, name)
+ return object.__delattr__(self, name)
+
+ def assert_called_with(self, *args, **kwargs):
+ """
+ assert that the mock was called with the specified arguments.
+
+ Raises an AttributeError if the args and keyword args passed in are
+ different to the last call to the mock.
+ """
+ assert self.call_args == (args, kwargs), 'Expected: %s\nCalled with: %s' % ((args, kwargs), self.call_args)
+
+
+class callargs(tuple):
+ """
+ A tuple for holding the results of a call to a mock, either in the form
+ `(args, kwargs)` or `(name, args, kwargs)`.
+
+ If args or kwargs are empty then a callargs tuple will compare equal to
+ a tuple without those values. This makes comparisons less verbose::
+
+ callargs('name', (), {}) == ('name',)
+ callargs('name', (1,), {}) == ('name', (1,))
+ callargs((), {'a': 'b'}) == ({'a': 'b'},)
+ """
+ def __eq__(self, other):
+ if len(self) == 3:
+ if other[0] != self[0]:
+ return False
+ args_kwargs = self[1:]
+ other_args_kwargs = other[1:]
+ else:
+ args_kwargs = tuple(self)
+ other_args_kwargs = other
+
+ if len(other_args_kwargs) == 0:
+ other_args, other_kwargs = (), {}
+ elif len(other_args_kwargs) == 1:
+ if isinstance(other_args_kwargs[0], tuple):
+ other_args = other_args_kwargs[0]
+ other_kwargs = {}
+ else:
+ other_args = ()
+ other_kwargs = other_args_kwargs[0]
+ else:
+ other_args, other_kwargs = other_args_kwargs
+
+ return tuple(args_kwargs) == (other_args, other_kwargs)
+
+def _dot_lookup(thing, comp, import_path):
+ try:
+ return getattr(thing, comp)
+ except AttributeError:
+ __import__(import_path)
+ return getattr(thing, comp)
+
+
+def _importer(target):
+ components = target.split('.')
+ import_path = components.pop(0)
+ thing = __import__(import_path)
+
+ for comp in components:
+ import_path += ".%s" % comp
+ thing = _dot_lookup(thing, comp, import_path)
+ return thing
+
+
+class _patch(object):
+ def __init__(self, target, attribute, new, spec, create, mocksignature):
+ self.target = target
+ self.attribute = attribute
+ self.new = new
+ self.spec = spec
+ self.create = create
+ self.has_local = False
+ self.mocksignature = mocksignature
+
+
+ def copy(self):
+ return _patch(self.target, self.attribute, self.new,
+ self.spec, self.create, self.mocksignature)
+
+
+ def __call__(self, func):
+ if isinstance(func, class_types):
+ return self.decorate_class(func)
+ else:
+ return self.decorate_callable(func)
+
+ def decorate_class(self, klass):
+ for attr in dir(klass):
+ attr_value = getattr(klass, attr)
+ if attr.startswith("test") and hasattr(attr_value, "__call__"):
+ setattr(klass, attr, self.copy()(attr_value))
+ return klass
+
+ def decorate_callable(self, func):
+ if hasattr(func, 'patchings'):
+ func.patchings.append(self)
+ return func
+
+ @wraps(func)
+ def patched(*args, **keywargs):
+ # don't use a with here (backwards compatability with 2.5)
+ extra_args = []
+ for patching in patched.patchings:
+ arg = patching.__enter__()
+ if patching.new is DEFAULT:
+ extra_args.append(arg)
+ args += tuple(extra_args)
+ try:
+ return func(*args, **keywargs)
+ finally:
+ for patching in reversed(getattr(patched, 'patchings', [])):
+ patching.__exit__()
+
+ patched.patchings = [self]
+ if hasattr(func, 'func_code'):
+ # not in Python 3
+ patched.compat_co_firstlineno = getattr(func, "compat_co_firstlineno",
+ func.func_code.co_firstlineno)
+ return patched
+
+
+ def get_original(self):
+ target = self.target
+ name = self.attribute
+ create = self.create
+
+ original = DEFAULT
+ if _has_local_attr(target, name):
+ try:
+ original = target.__dict__[name]
+ except AttributeError:
+ # for instances of classes with slots, they have no __dict__
+ original = getattr(target, name)
+ elif not create and not hasattr(target, name):
+ raise AttributeError("%s does not have the attribute %r" % (target, name))
+ return original
+
+
+ def __enter__(self):
+ new, spec, = self.new, self.spec
+ original = self.get_original()
+ if new is DEFAULT:
+ # XXXX what if original is DEFAULT - shouldn't use it as a spec
+ inherit = False
+ if spec == True:
+ # set spec to the object we are replacing
+ spec = original
+ if isinstance(spec, class_types):
+ inherit = True
+ new = Mock(spec=spec)
+ if inherit:
+ new.return_value = Mock(spec=spec)
+ new_attr = new
+ if self.mocksignature:
+ new_attr = mocksignature(original, new)
+
+ self.temp_original = original
+ setattr(self.target, self.attribute, new_attr)
+ return new
+
+
+ def __exit__(self, *_):
+ if self.temp_original is not DEFAULT:
+ setattr(self.target, self.attribute, self.temp_original)
+ else:
+ delattr(self.target, self.attribute)
+ del self.temp_original
+
+
+def _patch_object(target, attribute, new=DEFAULT, spec=None, create=False, mocksignature=False):
+ """
+ patch.object(target, attribute, new=DEFAULT, spec=None, create=False, mocksignature=False)
+
+ patch the named member (`attribute`) on an object (`target`) with a mock
+ object.
+
+ Arguments new, spec, create and mocksignature have the same meaning as for
+ patch.
+ """
+ return _patch(target, attribute, new, spec, create, mocksignature)
+
+def patch_object(*args, **kwargs):
+ "A deprecated form of patch.object(...)"
+ warnings.warn(('Please use patch.object instead.'), DeprecationWarning, 2)
+ return _patch_object(*args, **kwargs)
+
+def patch(target, new=DEFAULT, spec=None, create=False, mocksignature=False):
+ """
+ patch(target, new=DEFAULT, spec=None, create=False, mocksignature=False)
+
+ ``patch`` acts as a function decorator or a context manager. Inside the body
+ of the function or with statement, the ``target`` (specified in the form
+ 'PackageName.ModuleName.ClassName') is patched with a ``new`` object. When the
+ function/with statement exits the patch is undone.
+
+ The target is imported and the specified attribute patched with the new object
+ - so it must be importable from the environment you are calling the decorator
+ from.
+
+ If ``new`` is omitted, then a new ``Mock`` is created and passed in as an
+ extra argument to the decorated function.
+
+ The ``spec`` keyword argument is passed to the ``Mock`` if patch is creating
+ one for you.
+
+ In addition you can pass ``spec=True``, which causes patch to pass in the
+ object being mocked as the spec object.
+
+ If ``mocksignature`` is True then the patch will be done with a function
+ created by mocking the one being replaced.
+
+ patch.dict(...) and patch.object(...) are available for alternate use-cases.
+ """
+ try:
+ target, attribute = target.rsplit('.', 1)
+ except (TypeError, ValueError):
+ raise TypeError("Need a valid target to patch. You supplied: %r" % (target,))
+ target = _importer(target)
+ return _patch(target, attribute, new, spec, create, mocksignature)
+
+class _patch_dict(object):
+ """
+ patch.dict(in_dict, values=(), clear=False)
+
+ Patch a dictionary and restore the dictionary to its original state after
+ the test.
+
+ `in_dict` can be a dictionary or a mapping like container. If it is a
+ mapping then it must at least support getting, setting and deleting items
+ plus iterating over keys.
+
+ `in_dict` can also be a string specifying the name of the dictionary, which
+ will then be fetched by importing it.
+
+ `values` can be a dictionary of values to set in the dictionary. `values`
+ can also be an iterable of ``(key, value)`` pairs.
+
+ If `clear` is True then the dictionary will be cleared before the new
+ values are set.
+ """
+
+ def __init__(self, in_dict, values=(), clear=False):
+ if isinstance(in_dict, basestring):
+ in_dict = _importer(in_dict)
+ self.in_dict = in_dict
+ # support any argument supported by dict(...) constructor
+ self.values = dict(values)
+ self.clear = clear
+ self._original = None
+
+ def __call__(self, f):
+ @wraps(f)
+ def _inner(*args, **kw):
+ self._patch_dict()
+ try:
+ return f(*args, **kw)
+ finally:
+ self._unpatch_dict()
+
+ return _inner
+
+ def __enter__(self):
+ self._patch_dict()
+
+ def _patch_dict(self):
+ values = self.values
+ in_dict = self.in_dict
+ clear = self.clear
+
+ try:
+ original = in_dict.copy()
+ except AttributeError:
+ # dict like object with no copy method
+ # must support iteration over keys
+ original = {}
+ for key in in_dict:
+ original[key] = in_dict[key]
+ self._original = original
+
+ if clear:
+ _clear_dict(in_dict)
+
+ try:
+ in_dict.update(values)
+ except AttributeError:
+ # dict like object with no update method
+ for key in values:
+ in_dict[key] = values[key]
+
+ def _unpatch_dict(self):
+ in_dict = self.in_dict
+ original = self._original
+
+ _clear_dict(in_dict)
+
+ try:
+ in_dict.update(original)
+ except AttributeError:
+ for key in original:
+ in_dict[key] = original[key]
+
+
+ def __exit__(self, *args):
+ self._unpatch_dict()
+ return False
+
+
+def _clear_dict(in_dict):
+ try:
+ in_dict.clear()
+ except AttributeError:
+ keys = list(in_dict)
+ for key in keys:
+ del in_dict[key]
+
+
+patch.object = _patch_object
+patch.dict = _patch_dict
+
+def _has_local_attr(obj, name):
+ try:
+ return name in vars(obj)
+ except TypeError:
+ # objects without a __dict__
+ return hasattr(obj, name)
+
+
+magic_methods = (
+ "lt le gt ge eq ne "
+ "getitem setitem delitem "
+ "len contains iter "
+ "hash repr str "
+ "enter exit "
+ "divmod neg pos abs invert "
+ "complex int float index "
+)
+
+numerics = "add sub mul div truediv floordiv mod lshift rshift and xor or pow "
+inplace = ' '.join('i%s' % n for n in numerics.split())
+right = ' '.join('r%s' % n for n in numerics.split())
+extra = ''
+if inPy3k:
+ extra = 'bool next '
+else:
+ extra = 'unicode long nonzero oct hex '
+# __truediv__ and __rtruediv__ not available in Python 3 either
+
+# not including __prepare__, __instancecheck__, __subclasscheck__
+# (as they are metaclass methods)
+# __del__ is not supported at all as it causes problems if it exists
+
+_non_defaults = set('__%s__' % method for method in [
+ 'cmp', 'getslice', 'setslice', 'coerce', 'subclasses',
+ 'dir', 'format', 'get', 'set', 'delete', 'reversed',
+ 'missing',
+])
+
+def get_method(name, func):
+ def method(self, *args, **kw):
+ return func(self, *args, **kw)
+ method.__name__ = name
+ return method
+
+_magics = set('__%s__' % method for method in ' '.join([magic_methods, numerics, inplace, right, extra]).split())
+
+_all_magics = _magics | _non_defaults
+
+
+_side_effects = {
+ '__hash__': lambda self: object.__hash__(self),
+ '__repr__': lambda self: object.__repr__(self),
+ '__str__': lambda self: object.__str__(self),
+ '__unicode__': lambda self: unicode(object.__str__(self)),
+}
+
+_return_values = {
+ '__int__': 0,
+ '__contains__': False,
+ '__len__': 0,
+ '__iter__': iter([]),
+ '__exit__': False,
+ '__complex__': 0j,
+ '__float__': 0.0,
+ '__bool__': True,
+ '__nonzero__': True,
+ '__oct__': '0',
+ '__hex__': '0x0',
+ '__long__': long(0),
+ '__index__': 0,
+}
+
+def _set_return_value(mock, method, name):
+ if name in _side_effects:
+ func = _side_effects[name]
+ def wrap(*args, **kw):
+ if method._return_value is DEFAULT:
+ return func(mock)
+ return method._return_value
+ method.side_effect = wrap
+ elif name in _return_values:
+ method.return_value = _return_values[name]
+
+
+class MagicMock(Mock):
+ """
+ MagicMock is a subclass of :Mock with default implementations
+ of most of the magic methods. You can use MagicMock without having to
+ configure the magic methods yourself.
+ """
+ def __init__(self, *args, **kw):
+ Mock.__init__(self, *args, **kw)
+ for entry in _magics:
+ # could specify parent?
+ m = Mock()
+ setattr(self, entry, m)
+ _set_return_value(self, m, entry)
diff --git a/setup.py b/setup.py
index d081cfb..18882f5 100755
--- a/setup.py
+++ b/setup.py
@@ -49,7 +49,7 @@ setup(
name=NAME,
version=__version__,
py_modules=MODULES,
-
+
# metadata for upload to PyPI
author=AUTHOR,
author_email=AUTHOR_EMAIL,
@@ -58,4 +58,4 @@ setup(
keywords=KEYWORDS,
url=URL,
classifiers=CLASSIFIERS,
-)
+) \ No newline at end of file
diff --git a/tests/__init__.py b/tests/__init__.py
index ca641cb..6d5f87c 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,4 +1,3 @@
-# Copyright (C) 2007-2010 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
+# Copyright (C) 2007-2010 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
diff --git a/tests/support.py b/tests/support.py
index 5ea466f..c3c4189 100644
--- a/tests/support.py
+++ b/tests/support.py
@@ -24,6 +24,6 @@ with_available = sys.version_info[:2] >= (2, 5)
class SomeClass(object):
class_attribute = None
-
+
def wibble(self):
- pass
+ pass \ No newline at end of file
diff --git a/tests/support_with.py b/tests/support_with.py
index f9cb6ce..9c04691 100644
--- a/tests/support_with.py
+++ b/tests/support_with.py
@@ -43,14 +43,14 @@ except ImportError:
self._record = record
self._module = sys.modules['warnings']
self._entered = False
-
+
def __repr__(self):
args = []
if self._record:
args.append("record=True")
name = type(self).__name__
return "%s(%s)" % (name, ", ".join(args))
-
+
def __enter__(self):
if self._entered:
raise RuntimeError("Cannot enter %r twice" % self)
@@ -66,7 +66,7 @@ except ImportError:
return log
else:
return None
-
+
def __exit__(self, *exc_info):
if not self._entered:
raise RuntimeError("Cannot exit %r without entering first" % self)
@@ -90,4 +90,4 @@ def examine_warnings(func):
def wrapper():
with catch_warnings(record=True) as ws:
func(ws)
- return wrapper
+ return wrapper \ No newline at end of file
diff --git a/tests/testmagicmethods.py b/tests/testmagicmethods.py
index f03b60a..9495764 100644
--- a/tests/testmagicmethods.py
+++ b/tests/testmagicmethods.py
@@ -1,268 +1,267 @@
-# Copyright (C) 2007-2010 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-from tests.support import unittest2, inPy3k
-
-try:
- unicode
-except NameError:
- # Python 3
- unicode = str
- long = int
-
-import inspect
-from mock import Mock, MagicMock, _magics
-
-
-
-class TestMockingMagicMethods(unittest2.TestCase):
-
- def testDeletingMagicMethods(self):
- mock = Mock()
- self.assertFalse(hasattr(mock, '__getitem__'))
-
- mock.__getitem__ = Mock()
- self.assertTrue(hasattr(mock, '__getitem__'))
-
- del mock.__getitem__
- self.assertFalse(hasattr(mock, '__getitem__'))
-
-
- def testMagicMethodWrapping(self):
- mock = Mock()
- def f(self, name):
- return self, 'fish'
-
- mock.__getitem__ = f
- self.assertFalse(mock.__getitem__ is f)
- self.assertEqual(mock['foo'], (mock, 'fish'))
-
- # When you pull the function back of the *instance*
- # the first argument (self) is removed
- def instance_f(name):
- pass
- self.assertEqual(inspect.getargspec(mock.__getitem__), inspect.getargspec(instance_f))
-
- mock.__getitem__ = mock
- self.assertTrue(mock.__getitem__ is mock)
-
-
- def testRepr(self):
- mock = Mock()
- self.assertEqual(repr(mock), object.__repr__(mock))
- mock.__repr__ = lambda s: 'foo'
- self.assertEqual(repr(mock), 'foo')
-
-
- def testStr(self):
- mock = Mock()
- self.assertEqual(str(mock), object.__str__(mock))
- mock.__str__ = lambda s: 'foo'
- self.assertEqual(str(mock), 'foo')
-
- @unittest2.skipIf(inPy3k, "no unicode in Python 3")
- def testUnicode(self):
- mock = Mock()
- self.assertEqual(unicode(mock), unicode(str(mock)))
-
- mock.__unicode__ = lambda s: unicode('foo')
- self.assertEqual(unicode(mock), unicode('foo'))
-
-
- def testDictMethods(self):
- mock = Mock()
-
- self.assertRaises(TypeError, lambda: mock['foo'])
- def _del():
- del mock['foo']
- def _set():
- mock['foo'] = 3
- self.assertRaises(TypeError, _del)
- self.assertRaises(TypeError, _set)
-
- _dict = {}
- def getitem(s, name):
- return _dict[name]
- def setitem(s, name, value):
- _dict[name] = value
- def delitem(s, name):
- del _dict[name]
-
- mock.__setitem__ = setitem
- mock.__getitem__ = getitem
- mock.__delitem__ = delitem
-
- self.assertRaises(KeyError, lambda: mock['foo'])
- mock['foo'] = 'bar'
- self.assertEqual(_dict, {'foo': 'bar'})
- self.assertEqual(mock['foo'], 'bar')
- del mock['foo']
- self.assertEqual(_dict, {})
-
-
- def testNumeric(self):
- original = mock = Mock()
- mock.value = 0
-
- self.assertRaises(TypeError, lambda: mock + 3)
-
- def add(self, other):
- mock.value += other
- return self
- mock.__add__ = add
- self.assertEqual(mock + 3, mock)
- self.assertEqual(mock.value, 3)
-
- del mock.__add__
- def iadd(mock):
- mock += 3
- self.assertRaises(TypeError, iadd, mock)
- mock.__iadd__ = add
- mock += 6
- self.assertEqual(mock, original)
- self.assertEqual(mock.value, 9)
-
- self.assertRaises(TypeError, lambda: 3 + mock)
- mock.__radd__ = add
- self.assertEqual(7 + mock, mock)
- self.assertEqual(mock.value, 16)
-
-
- def testHash(self):
- mock = Mock()
- # test delegation
- self.assertEqual(hash(mock), Mock.__hash__(mock))
-
- def _hash(s):
- return 3
- mock.__hash__ = _hash
- self.assertEqual(hash(mock), 3)
-
-
- def testNonZero(self):
- m = Mock()
- self.assertTrue(bool(m))
-
- nonzero = lambda s: False
- if not inPy3k:
- m.__nonzero__ = nonzero
- else:
- m.__bool__ = nonzero
-
- self.assertFalse(bool(m))
-
-
- def testComparison(self):
- if not inPy3k:
- # incomparable in Python 3
- self. assertEqual(Mock() < 3, object() < 3)
- self. assertEqual(Mock() > 3, object() > 3)
- self. assertEqual(Mock() <= 3, object() <= 3)
- self. assertEqual(Mock() >= 3, object() >= 3)
-
- mock = Mock()
- def comp(s, o):
- return True
- mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp
- self. assertTrue(mock < 3)
- self. assertTrue(mock > 3)
- self. assertTrue(mock <= 3)
- self. assertTrue(mock >= 3)
-
-
- def testEquality(self):
- mock = Mock()
- self.assertEqual(mock, mock)
- self.assertNotEqual(mock, Mock())
- self.assertNotEqual(mock, 3)
-
- def eq(self, other):
- return other == 3
- mock.__eq__ = eq
- self.assertTrue(mock == 3)
- self.assertFalse(mock == 4)
-
- def ne(self, other):
- return other == 3
- mock.__ne__ = ne
- self.assertTrue(mock != 3)
- self.assertFalse(mock != 4)
-
-
- def testLenContainsIter(self):
- mock = Mock()
-
- self.assertRaises(TypeError, len, mock)
- self.assertRaises(TypeError, iter, mock)
- self.assertRaises(TypeError, lambda: 'foo' in mock)
-
- mock.__len__ = lambda s: 6
- self.assertEqual(len(mock), 6)
-
- mock.__contains__ = lambda s, o: o == 3
- self.assertTrue(3 in mock)
- self.assertFalse(6 in mock)
-
- mock.__iter__ = lambda s: iter('foobarbaz')
- self.assertEqual(list(mock), list('foobarbaz'))
-
-
- def testMagicMock(self):
- mock = MagicMock()
-
- mock.__iter__.return_value = iter([1, 2, 3])
- self.assertEqual(list(mock), [1, 2, 3])
-
- if inPy3k:
- mock.__bool__.return_value = False
- self.assertFalse(hasattr(mock, '__nonzero__'))
- else:
- mock.__nonzero__.return_value = False
- self.assertFalse(hasattr(mock, '__bool__'))
-
- self.assertFalse(bool(mock))
-
- for entry in _magics:
- self.assertTrue(hasattr(mock, entry))
- self.assertFalse(hasattr(mock, '__imaginery__'))
-
-
- def testMagicMockDefaults(self):
- mock = MagicMock()
- self.assertEqual(int(mock), 0)
- self.assertEqual(complex(mock), 0j)
- self.assertEqual(float(mock), 0.0)
- self.assertEqual(long(mock), long(0))
- self.assertNotIn(object(), mock)
- self.assertEqual(len(mock), 0)
- self.assertEqual(list(mock), [])
- self.assertEqual(hash(mock), object.__hash__(mock))
- self.assertEqual(repr(mock), object.__repr__(mock))
- self.assertEqual(str(mock), object.__str__(mock))
- self.assertEqual(unicode(mock), object.__str__(mock))
- self.assertIsInstance(unicode(mock), unicode)
- self.assertTrue(bool(mock))
- if not inPy3k:
- self.assertEqual(oct(mock), '0')
- else:
- # in Python 3 oct and hex use __index__
- # so these tests are for __index__ in py3k
- self.assertEqual(oct(mock), '0o0')
- self.assertEqual(hex(mock), '0x0')
-
-
- @unittest2.skipIf(inPy3k, "no __cmp__ in Python 3")
- def testNonDefaultMagicMethods(self):
- mock = MagicMock()
- self.assertRaises(AttributeError, lambda: mock.__cmp__)
-
- mock = Mock()
- mock.__cmp__ = lambda s, o: 0
-
- self.assertEqual(mock, object())
-
-
-if __name__ == '__main__':
- unittest2.main()
-
+# Copyright (C) 2007-2010 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+
+from tests.support import unittest2, inPy3k
+
+try:
+ unicode
+except NameError:
+ # Python 3
+ unicode = str
+ long = int
+
+import inspect
+from mock import Mock, MagicMock, _magics
+
+
+
+class TestMockingMagicMethods(unittest2.TestCase):
+
+ def testDeletingMagicMethods(self):
+ mock = Mock()
+ self.assertFalse(hasattr(mock, '__getitem__'))
+
+ mock.__getitem__ = Mock()
+ self.assertTrue(hasattr(mock, '__getitem__'))
+
+ del mock.__getitem__
+ self.assertFalse(hasattr(mock, '__getitem__'))
+
+
+ def testMagicMethodWrapping(self):
+ mock = Mock()
+ def f(self, name):
+ return self, 'fish'
+
+ mock.__getitem__ = f
+ self.assertFalse(mock.__getitem__ is f)
+ self.assertEqual(mock['foo'], (mock, 'fish'))
+
+ # When you pull the function back of the *instance*
+ # the first argument (self) is removed
+ def instance_f(name):
+ pass
+ self.assertEqual(inspect.getargspec(mock.__getitem__), inspect.getargspec(instance_f))
+
+ mock.__getitem__ = mock
+ self.assertTrue(mock.__getitem__ is mock)
+
+
+ def testRepr(self):
+ mock = Mock()
+ self.assertEqual(repr(mock), object.__repr__(mock))
+ mock.__repr__ = lambda s: 'foo'
+ self.assertEqual(repr(mock), 'foo')
+
+
+ def testStr(self):
+ mock = Mock()
+ self.assertEqual(str(mock), object.__str__(mock))
+ mock.__str__ = lambda s: 'foo'
+ self.assertEqual(str(mock), 'foo')
+
+ @unittest2.skipIf(inPy3k, "no unicode in Python 3")
+ def testUnicode(self):
+ mock = Mock()
+ self.assertEqual(unicode(mock), unicode(str(mock)))
+
+ mock.__unicode__ = lambda s: unicode('foo')
+ self.assertEqual(unicode(mock), unicode('foo'))
+
+
+ def testDictMethods(self):
+ mock = Mock()
+
+ self.assertRaises(TypeError, lambda: mock['foo'])
+ def _del():
+ del mock['foo']
+ def _set():
+ mock['foo'] = 3
+ self.assertRaises(TypeError, _del)
+ self.assertRaises(TypeError, _set)
+
+ _dict = {}
+ def getitem(s, name):
+ return _dict[name]
+ def setitem(s, name, value):
+ _dict[name] = value
+ def delitem(s, name):
+ del _dict[name]
+
+ mock.__setitem__ = setitem
+ mock.__getitem__ = getitem
+ mock.__delitem__ = delitem
+
+ self.assertRaises(KeyError, lambda: mock['foo'])
+ mock['foo'] = 'bar'
+ self.assertEqual(_dict, {'foo': 'bar'})
+ self.assertEqual(mock['foo'], 'bar')
+ del mock['foo']
+ self.assertEqual(_dict, {})
+
+
+ def testNumeric(self):
+ original = mock = Mock()
+ mock.value = 0
+
+ self.assertRaises(TypeError, lambda: mock + 3)
+
+ def add(self, other):
+ mock.value += other
+ return self
+ mock.__add__ = add
+ self.assertEqual(mock + 3, mock)
+ self.assertEqual(mock.value, 3)
+
+ del mock.__add__
+ def iadd(mock):
+ mock += 3
+ self.assertRaises(TypeError, iadd, mock)
+ mock.__iadd__ = add
+ mock += 6
+ self.assertEqual(mock, original)
+ self.assertEqual(mock.value, 9)
+
+ self.assertRaises(TypeError, lambda: 3 + mock)
+ mock.__radd__ = add
+ self.assertEqual(7 + mock, mock)
+ self.assertEqual(mock.value, 16)
+
+
+ def testHash(self):
+ mock = Mock()
+ # test delegation
+ self.assertEqual(hash(mock), Mock.__hash__(mock))
+
+ def _hash(s):
+ return 3
+ mock.__hash__ = _hash
+ self.assertEqual(hash(mock), 3)
+
+
+ def testNonZero(self):
+ m = Mock()
+ self.assertTrue(bool(m))
+
+ nonzero = lambda s: False
+ if not inPy3k:
+ m.__nonzero__ = nonzero
+ else:
+ m.__bool__ = nonzero
+
+ self.assertFalse(bool(m))
+
+
+ def testComparison(self):
+ if not inPy3k:
+ # incomparable in Python 3
+ self. assertEqual(Mock() < 3, object() < 3)
+ self. assertEqual(Mock() > 3, object() > 3)
+ self. assertEqual(Mock() <= 3, object() <= 3)
+ self. assertEqual(Mock() >= 3, object() >= 3)
+
+ mock = Mock()
+ def comp(s, o):
+ return True
+ mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp
+ self. assertTrue(mock < 3)
+ self. assertTrue(mock > 3)
+ self. assertTrue(mock <= 3)
+ self. assertTrue(mock >= 3)
+
+
+ def testEquality(self):
+ mock = Mock()
+ self.assertEqual(mock, mock)
+ self.assertNotEqual(mock, Mock())
+ self.assertNotEqual(mock, 3)
+
+ def eq(self, other):
+ return other == 3
+ mock.__eq__ = eq
+ self.assertTrue(mock == 3)
+ self.assertFalse(mock == 4)
+
+ def ne(self, other):
+ return other == 3
+ mock.__ne__ = ne
+ self.assertTrue(mock != 3)
+ self.assertFalse(mock != 4)
+
+
+ def testLenContainsIter(self):
+ mock = Mock()
+
+ self.assertRaises(TypeError, len, mock)
+ self.assertRaises(TypeError, iter, mock)
+ self.assertRaises(TypeError, lambda: 'foo' in mock)
+
+ mock.__len__ = lambda s: 6
+ self.assertEqual(len(mock), 6)
+
+ mock.__contains__ = lambda s, o: o == 3
+ self.assertTrue(3 in mock)
+ self.assertFalse(6 in mock)
+
+ mock.__iter__ = lambda s: iter('foobarbaz')
+ self.assertEqual(list(mock), list('foobarbaz'))
+
+
+ def testMagicMock(self):
+ mock = MagicMock()
+
+ mock.__iter__.return_value = iter([1, 2, 3])
+ self.assertEqual(list(mock), [1, 2, 3])
+
+ if inPy3k:
+ mock.__bool__.return_value = False
+ self.assertFalse(hasattr(mock, '__nonzero__'))
+ else:
+ mock.__nonzero__.return_value = False
+ self.assertFalse(hasattr(mock, '__bool__'))
+
+ self.assertFalse(bool(mock))
+
+ for entry in _magics:
+ self.assertTrue(hasattr(mock, entry))
+ self.assertFalse(hasattr(mock, '__imaginery__'))
+
+
+ def testMagicMockDefaults(self):
+ mock = MagicMock()
+ self.assertEqual(int(mock), 0)
+ self.assertEqual(complex(mock), 0j)
+ self.assertEqual(float(mock), 0.0)
+ self.assertEqual(long(mock), long(0))
+ self.assertNotIn(object(), mock)
+ self.assertEqual(len(mock), 0)
+ self.assertEqual(list(mock), [])
+ self.assertEqual(hash(mock), object.__hash__(mock))
+ self.assertEqual(repr(mock), object.__repr__(mock))
+ self.assertEqual(str(mock), object.__str__(mock))
+ self.assertEqual(unicode(mock), object.__str__(mock))
+ self.assertIsInstance(unicode(mock), unicode)
+ self.assertTrue(bool(mock))
+ if not inPy3k:
+ self.assertEqual(oct(mock), '0')
+ else:
+ # in Python 3 oct and hex use __index__
+ # so these tests are for __index__ in py3k
+ self.assertEqual(oct(mock), '0o0')
+ self.assertEqual(hex(mock), '0x0')
+
+
+ @unittest2.skipIf(inPy3k, "no __cmp__ in Python 3")
+ def testNonDefaultMagicMethods(self):
+ mock = MagicMock()
+ self.assertRaises(AttributeError, lambda: mock.__cmp__)
+
+ mock = Mock()
+ mock.__cmp__ = lambda s, o: 0
+
+ self.assertEqual(mock, object())
+
+
+if __name__ == '__main__':
+ unittest2.main()
diff --git a/tests/testmock.py b/tests/testmock.py
index ec12bba..e0e3743 100644
--- a/tests/testmock.py
+++ b/tests/testmock.py
@@ -1,307 +1,306 @@
-# Copyright (C) 2007-2010 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-from tests.support import unittest2
-
-from mock import Mock, sentinel, DEFAULT
-
-try:
- unicode
-except NameError:
- unicode = str
-
-
-class MockTest(unittest2.TestCase):
-
- def testAll(self):
- # if __all__ is badly defined then import * will raise an error
- # We have to exec it because you can't import * inside a method
- # in Python 3
- exec("from mock import *")
-
- def testConstructor(self):
- mock = Mock()
-
- self.assertFalse(mock.called, "called not initialised correctly")
- self.assertEqual(mock.call_count, 0, "call_count not initialised correctly")
- self.assertTrue(isinstance(mock.return_value, Mock), "return_value not initialised correctly")
-
- self.assertEqual(mock.call_args, None, "call_args not initialised correctly")
- self.assertEqual(mock.call_args_list, [], "call_args_list not initialised correctly")
- self.assertEqual(mock.method_calls, [],
- "method_calls not initialised correctly")
-
- # Can't use hasattr for this test as it always returns True on a mock...
- self.assertFalse('_items' in mock.__dict__, "default mock should not have '_items' attribute")
-
- self.assertIsNone(mock._parent, "parent not initialised correctly")
- self.assertIsNone(mock._methods, "methods not initialised correctly")
- self.assertEqual(mock._children, {}, "children not initialised incorrectly")
-
- def testUnicodeNotBroken(self):
- # This used to raise an exception with Python 2.5 and Mock 0.4
- unicode(Mock())
-
- def testReturnValueInConstructor(self):
- mock = Mock(return_value=None)
- self.assertIsNone(mock.return_value, "return value in constructor not honoured")
-
-
- def testSideEffect(self):
- mock = Mock()
-
- def effect(*args, **kwargs):
- raise SystemError('kablooie')
-
- mock.side_effect = effect
- self.assertRaises(SystemError, mock, 1, 2, fish=3)
- mock.assert_called_with(1, 2, fish=3)
-
- results = [1, 2, 3]
- def effect():
- return results.pop()
- mock.side_effect = effect
-
- self.assertEqual([mock(), mock(), mock()], [3, 2, 1],
- "side effect not used correctly")
-
- mock = Mock(side_effect=sentinel.SideEffect)
- self.assertEqual(mock.side_effect, sentinel.SideEffect,
- "side effect in constructor not used")
-
- def side_effect():
- return DEFAULT
- mock = Mock(side_effect=side_effect, return_value=sentinel.RETURN)
- self.assertEqual(mock(), sentinel.RETURN)
-
-
- def testReset(self):
- parent = Mock()
- spec = ["something"]
- mock = Mock(name="child", parent=parent, spec=spec)
- mock(sentinel.Something, something=sentinel.SomethingElse)
- something = mock.something
- mock.something()
- mock.side_effect = sentinel.SideEffect
- return_value = mock.return_value
- return_value()
-
- mock.reset_mock()
-
- self.assertEqual(mock._name, "child", "name incorrectly reset")
- self.assertEqual(mock._parent, parent, "parent incorrectly reset")
- self.assertEqual(mock._methods, spec, "methods incorrectly reset")
-
- self.assertFalse(mock.called, "called not reset")
- self.assertEqual(mock.call_count, 0, "call_count not reset")
- self.assertEqual(mock.call_args, None, "call_args not reset")
- self.assertEqual(mock.call_args_list, [], "call_args_list not reset")
- self.assertEqual(mock.method_calls, [],
- "method_calls not initialised correctly: %r != %r" % (mock.method_calls, []))
-
- self.assertEqual(mock.side_effect, sentinel.SideEffect,
- "side_effect incorrectly reset")
- self.assertEqual(mock.return_value, return_value,
- "return_value incorrectly reset")
- self.assertFalse(return_value.called, "return value mock not reset")
- self.assertEqual(mock._children, {'something': something},
- "children reset incorrectly")
- self.assertEqual(mock.something, something,
- "children incorrectly cleared")
- self.assertFalse(mock.something.called, "child not reset")
-
-
- def testCall(self):
- mock = Mock()
- self.assertTrue(isinstance(mock.return_value, Mock), "Default return_value should be a Mock")
-
- result = mock()
- self.assertEqual(mock(), result, "different result from consecutive calls")
- mock.reset_mock()
-
- ret_val = mock(sentinel.Arg)
- self.assertTrue(mock.called, "called not set")
- self.assertEqual(mock.call_count, 1, "call_count incoreect")
- self.assertEqual(mock.call_args, ((sentinel.Arg,), {}), "call_args not set")
- self.assertEqual(mock.call_args_list, [((sentinel.Arg,), {})], "call_args_list not initialised correctly")
-
- mock.return_value = sentinel.ReturnValue
- ret_val = mock(sentinel.Arg, key=sentinel.KeyArg)
- self.assertEqual(ret_val, sentinel.ReturnValue, "incorrect return value")
-
- self.assertEqual(mock.call_count, 2, "call_count incorrect")
- self.assertEqual(mock.call_args, ((sentinel.Arg,), {'key': sentinel.KeyArg}), "call_args not set")
- self.assertEqual(mock.call_args_list, [((sentinel.Arg,), {}), ((sentinel.Arg,), {'key': sentinel.KeyArg})], "call_args_list not set")
-
- def testCallArgsComparison(self):
- mock = Mock()
- mock()
- mock(sentinel.Arg)
- mock(kw=sentinel.Kwarg)
- mock(sentinel.Arg, kw=sentinel.Kwarg)
- self.assertEqual(mock.call_args_list, [(),
- ((sentinel.Arg,),),
- ({"kw": sentinel.Kwarg},),
- ((sentinel.Arg,), {"kw": sentinel.Kwarg})])
- self.assertEqual(mock.call_args, ((sentinel.Arg,), {"kw": sentinel.Kwarg}))
-
- def testAssertCalledWith(self):
- mock = Mock()
- mock()
-
- # Will raise an exception if it fails
- mock.assert_called_with()
- self.assertRaises(AssertionError, mock.assert_called_with, 1)
-
- mock.reset_mock()
- self.assertRaises(AssertionError, mock.assert_called_with)
-
- mock(1, 2, 3, a='fish', b='nothing')
- mock.assert_called_with(1, 2, 3, a='fish', b='nothing')
-
-
- def testAttributeAccessReturnsMocks(self):
- mock = Mock()
- something = mock.something
- self.assertTrue(isinstance(something, Mock), "attribute isn't a mock")
- self.assertEqual(mock.something, something, "different attributes returned for same name")
-
- # Usage example
- mock = Mock()
- mock.something.return_value = 3
-
- self.assertEqual(mock.something(), 3, "method returned wrong value")
- self.assertTrue(mock.something.called, "method didn't record being called")
-
-
- def testAttributesHaveNameAndParentSet(self):
- mock = Mock()
- something = mock.something
-
- self.assertEqual(something._name, "something", "attribute name not set correctly")
- self.assertEqual(something._parent, mock, "attribute parent not set correctly")
-
-
- def testMethodCallsRecorded(self):
- mock = Mock()
- mock.something(3, fish=None)
- mock.something_else.something(6, cake=sentinel.Cake)
-
- self.assertEqual(mock.something_else.method_calls,
- [("something", (6,), {'cake': sentinel.Cake})],
- "method calls not recorded correctly")
- self.assertEqual(mock.method_calls,
- [("something", (3,), {'fish': None}),
- ("something_else.something", (6,), {'cake': sentinel.Cake})],
- "method calls not recorded correctly")
-
- def testMethodCallsCompareEasily(self):
- mock = Mock()
- mock.something()
- self.assertEqual(mock.method_calls, [('something',)])
- self.assertEqual(mock.method_calls, [('something', (), {})])
-
- mock = Mock()
- mock.something('different')
- self.assertEqual(mock.method_calls, [('something', ('different',))])
- self.assertEqual(mock.method_calls, [('something', ('different',), {})])
-
- mock = Mock()
- mock.something(x=1)
- self.assertEqual(mock.method_calls, [('something', {'x': 1})])
- self.assertEqual(mock.method_calls, [('something', (), {'x': 1})])
-
- mock = Mock()
- mock.something('different', some='more')
- self.assertEqual(mock.method_calls, [('something', ('different',), {'some': 'more'})])
-
- def testOnlyAllowedMethodsExist(self):
- spec = ["something"]
- mock = Mock(spec=spec)
-
- # this should be allowed
- mock.something
- self.assertRaisesRegexp(AttributeError,
- "Mock object has no attribute 'something_else'",
- lambda: mock.something_else)
-
-
- def testFromSpec(self):
- class Something(object):
- x = 3
- __something__ = None
- def y(self):
- pass
-
- def testAttributes(mock):
- # should work
- mock.x
- mock.y
- self.assertRaisesRegexp(AttributeError,
- "Mock object has no attribute 'z'",
- lambda: mock.z)
- self.assertRaisesRegexp(AttributeError,
- "Mock object has no attribute '__something__'",
- lambda: mock.__something__)
-
- testAttributes(Mock(spec=Something))
- testAttributes(Mock(spec=Something()))
-
-
- def testWrapsCalls(self):
- real = Mock()
-
- mock = Mock(wraps=real)
- self.assertEqual(mock(), real())
-
- real.reset_mock()
-
- mock(1, 2, fish=3)
- real.assert_called_with(1, 2, fish=3)
-
-
- def testWrapsCallWithNonDefaultReturnValue(self):
- real = Mock()
-
- mock = Mock(wraps=real)
- mock.return_value = 3
-
- self.assertEqual(mock(), 3)
- self.assertFalse(real.called)
-
-
- def testWrapsAttributes(self):
- class Real(object):
- attribute = Mock()
-
- real = Real()
-
- mock = Mock(wraps=real)
- self.assertEqual(mock.attribute(), real.attribute())
- self.assertRaises(AttributeError, lambda: mock.fish)
-
- self.assertNotEqual(mock.attribute, real.attribute)
- result = mock.attribute.frog(1, 2, fish=3)
- Real.attribute.frog.assert_called_with(1, 2, fish=3)
- self.assertEqual(result, Real.attribute.frog())
-
-
- def testExceptionalSideEffect(self):
- mock = Mock(side_effect=AttributeError)
- self.assertRaises(AttributeError, mock)
-
- mock = Mock(side_effect=AttributeError('foo'))
- self.assertRaises(AttributeError, mock)
-
- def testBaseExceptionalSideEffect(self):
- mock = Mock(side_effect=KeyboardInterrupt)
- self.assertRaises(KeyboardInterrupt, mock)
-
- mock = Mock(side_effect=KeyboardInterrupt('foo'))
- self.assertRaises(KeyboardInterrupt, mock)
-
-
-if __name__ == '__main__':
- unittest2.main()
-
+# Copyright (C) 2007-2010 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+
+from tests.support import unittest2
+
+from mock import Mock, sentinel, DEFAULT
+
+try:
+ unicode
+except NameError:
+ unicode = str
+
+
+class MockTest(unittest2.TestCase):
+
+ def testAll(self):
+ # if __all__ is badly defined then import * will raise an error
+ # We have to exec it because you can't import * inside a method
+ # in Python 3
+ exec("from mock import *")
+
+ def testConstructor(self):
+ mock = Mock()
+
+ self.assertFalse(mock.called, "called not initialised correctly")
+ self.assertEqual(mock.call_count, 0, "call_count not initialised correctly")
+ self.assertTrue(isinstance(mock.return_value, Mock), "return_value not initialised correctly")
+
+ self.assertEqual(mock.call_args, None, "call_args not initialised correctly")
+ self.assertEqual(mock.call_args_list, [], "call_args_list not initialised correctly")
+ self.assertEqual(mock.method_calls, [],
+ "method_calls not initialised correctly")
+
+ # Can't use hasattr for this test as it always returns True on a mock...
+ self.assertFalse('_items' in mock.__dict__, "default mock should not have '_items' attribute")
+
+ self.assertIsNone(mock._parent, "parent not initialised correctly")
+ self.assertIsNone(mock._methods, "methods not initialised correctly")
+ self.assertEqual(mock._children, {}, "children not initialised incorrectly")
+
+ def testUnicodeNotBroken(self):
+ # This used to raise an exception with Python 2.5 and Mock 0.4
+ unicode(Mock())
+
+ def testReturnValueInConstructor(self):
+ mock = Mock(return_value=None)
+ self.assertIsNone(mock.return_value, "return value in constructor not honoured")
+
+
+ def testSideEffect(self):
+ mock = Mock()
+
+ def effect(*args, **kwargs):
+ raise SystemError('kablooie')
+
+ mock.side_effect = effect
+ self.assertRaises(SystemError, mock, 1, 2, fish=3)
+ mock.assert_called_with(1, 2, fish=3)
+
+ results = [1, 2, 3]
+ def effect():
+ return results.pop()
+ mock.side_effect = effect
+
+ self.assertEqual([mock(), mock(), mock()], [3, 2, 1],
+ "side effect not used correctly")
+
+ mock = Mock(side_effect=sentinel.SideEffect)
+ self.assertEqual(mock.side_effect, sentinel.SideEffect,
+ "side effect in constructor not used")
+
+ def side_effect():
+ return DEFAULT
+ mock = Mock(side_effect=side_effect, return_value=sentinel.RETURN)
+ self.assertEqual(mock(), sentinel.RETURN)
+
+
+ def testReset(self):
+ parent = Mock()
+ spec = ["something"]
+ mock = Mock(name="child", parent=parent, spec=spec)
+ mock(sentinel.Something, something=sentinel.SomethingElse)
+ something = mock.something
+ mock.something()
+ mock.side_effect = sentinel.SideEffect
+ return_value = mock.return_value
+ return_value()
+
+ mock.reset_mock()
+
+ self.assertEqual(mock._name, "child", "name incorrectly reset")
+ self.assertEqual(mock._parent, parent, "parent incorrectly reset")
+ self.assertEqual(mock._methods, spec, "methods incorrectly reset")
+
+ self.assertFalse(mock.called, "called not reset")
+ self.assertEqual(mock.call_count, 0, "call_count not reset")
+ self.assertEqual(mock.call_args, None, "call_args not reset")
+ self.assertEqual(mock.call_args_list, [], "call_args_list not reset")
+ self.assertEqual(mock.method_calls, [],
+ "method_calls not initialised correctly: %r != %r" % (mock.method_calls, []))
+
+ self.assertEqual(mock.side_effect, sentinel.SideEffect,
+ "side_effect incorrectly reset")
+ self.assertEqual(mock.return_value, return_value,
+ "return_value incorrectly reset")
+ self.assertFalse(return_value.called, "return value mock not reset")
+ self.assertEqual(mock._children, {'something': something},
+ "children reset incorrectly")
+ self.assertEqual(mock.something, something,
+ "children incorrectly cleared")
+ self.assertFalse(mock.something.called, "child not reset")
+
+
+ def testCall(self):
+ mock = Mock()
+ self.assertTrue(isinstance(mock.return_value, Mock), "Default return_value should be a Mock")
+
+ result = mock()
+ self.assertEqual(mock(), result, "different result from consecutive calls")
+ mock.reset_mock()
+
+ ret_val = mock(sentinel.Arg)
+ self.assertTrue(mock.called, "called not set")
+ self.assertEqual(mock.call_count, 1, "call_count incoreect")
+ self.assertEqual(mock.call_args, ((sentinel.Arg,), {}), "call_args not set")
+ self.assertEqual(mock.call_args_list, [((sentinel.Arg,), {})], "call_args_list not initialised correctly")
+
+ mock.return_value = sentinel.ReturnValue
+ ret_val = mock(sentinel.Arg, key=sentinel.KeyArg)
+ self.assertEqual(ret_val, sentinel.ReturnValue, "incorrect return value")
+
+ self.assertEqual(mock.call_count, 2, "call_count incorrect")
+ self.assertEqual(mock.call_args, ((sentinel.Arg,), {'key': sentinel.KeyArg}), "call_args not set")
+ self.assertEqual(mock.call_args_list, [((sentinel.Arg,), {}), ((sentinel.Arg,), {'key': sentinel.KeyArg})], "call_args_list not set")
+
+ def testCallArgsComparison(self):
+ mock = Mock()
+ mock()
+ mock(sentinel.Arg)
+ mock(kw=sentinel.Kwarg)
+ mock(sentinel.Arg, kw=sentinel.Kwarg)
+ self.assertEqual(mock.call_args_list, [(),
+ ((sentinel.Arg,),),
+ ({"kw": sentinel.Kwarg},),
+ ((sentinel.Arg,), {"kw": sentinel.Kwarg})])
+ self.assertEqual(mock.call_args, ((sentinel.Arg,), {"kw": sentinel.Kwarg}))
+
+ def testAssertCalledWith(self):
+ mock = Mock()
+ mock()
+
+ # Will raise an exception if it fails
+ mock.assert_called_with()
+ self.assertRaises(AssertionError, mock.assert_called_with, 1)
+
+ mock.reset_mock()
+ self.assertRaises(AssertionError, mock.assert_called_with)
+
+ mock(1, 2, 3, a='fish', b='nothing')
+ mock.assert_called_with(1, 2, 3, a='fish', b='nothing')
+
+
+ def testAttributeAccessReturnsMocks(self):
+ mock = Mock()
+ something = mock.something
+ self.assertTrue(isinstance(something, Mock), "attribute isn't a mock")
+ self.assertEqual(mock.something, something, "different attributes returned for same name")
+
+ # Usage example
+ mock = Mock()
+ mock.something.return_value = 3
+
+ self.assertEqual(mock.something(), 3, "method returned wrong value")
+ self.assertTrue(mock.something.called, "method didn't record being called")
+
+
+ def testAttributesHaveNameAndParentSet(self):
+ mock = Mock()
+ something = mock.something
+
+ self.assertEqual(something._name, "something", "attribute name not set correctly")
+ self.assertEqual(something._parent, mock, "attribute parent not set correctly")
+
+
+ def testMethodCallsRecorded(self):
+ mock = Mock()
+ mock.something(3, fish=None)
+ mock.something_else.something(6, cake=sentinel.Cake)
+
+ self.assertEqual(mock.something_else.method_calls,
+ [("something", (6,), {'cake': sentinel.Cake})],
+ "method calls not recorded correctly")
+ self.assertEqual(mock.method_calls,
+ [("something", (3,), {'fish': None}),
+ ("something_else.something", (6,), {'cake': sentinel.Cake})],
+ "method calls not recorded correctly")
+
+ def testMethodCallsCompareEasily(self):
+ mock = Mock()
+ mock.something()
+ self.assertEqual(mock.method_calls, [('something',)])
+ self.assertEqual(mock.method_calls, [('something', (), {})])
+
+ mock = Mock()
+ mock.something('different')
+ self.assertEqual(mock.method_calls, [('something', ('different',))])
+ self.assertEqual(mock.method_calls, [('something', ('different',), {})])
+
+ mock = Mock()
+ mock.something(x=1)
+ self.assertEqual(mock.method_calls, [('something', {'x': 1})])
+ self.assertEqual(mock.method_calls, [('something', (), {'x': 1})])
+
+ mock = Mock()
+ mock.something('different', some='more')
+ self.assertEqual(mock.method_calls, [('something', ('different',), {'some': 'more'})])
+
+ def testOnlyAllowedMethodsExist(self):
+ spec = ["something"]
+ mock = Mock(spec=spec)
+
+ # this should be allowed
+ mock.something
+ self.assertRaisesRegexp(AttributeError,
+ "Mock object has no attribute 'something_else'",
+ lambda: mock.something_else)
+
+
+ def testFromSpec(self):
+ class Something(object):
+ x = 3
+ __something__ = None
+ def y(self):
+ pass
+
+ def testAttributes(mock):
+ # should work
+ mock.x
+ mock.y
+ self.assertRaisesRegexp(AttributeError,
+ "Mock object has no attribute 'z'",
+ lambda: mock.z)
+ self.assertRaisesRegexp(AttributeError,
+ "Mock object has no attribute '__something__'",
+ lambda: mock.__something__)
+
+ testAttributes(Mock(spec=Something))
+ testAttributes(Mock(spec=Something()))
+
+
+ def testWrapsCalls(self):
+ real = Mock()
+
+ mock = Mock(wraps=real)
+ self.assertEqual(mock(), real())
+
+ real.reset_mock()
+
+ mock(1, 2, fish=3)
+ real.assert_called_with(1, 2, fish=3)
+
+
+ def testWrapsCallWithNonDefaultReturnValue(self):
+ real = Mock()
+
+ mock = Mock(wraps=real)
+ mock.return_value = 3
+
+ self.assertEqual(mock(), 3)
+ self.assertFalse(real.called)
+
+
+ def testWrapsAttributes(self):
+ class Real(object):
+ attribute = Mock()
+
+ real = Real()
+
+ mock = Mock(wraps=real)
+ self.assertEqual(mock.attribute(), real.attribute())
+ self.assertRaises(AttributeError, lambda: mock.fish)
+
+ self.assertNotEqual(mock.attribute, real.attribute)
+ result = mock.attribute.frog(1, 2, fish=3)
+ Real.attribute.frog.assert_called_with(1, 2, fish=3)
+ self.assertEqual(result, Real.attribute.frog())
+
+
+ def testExceptionalSideEffect(self):
+ mock = Mock(side_effect=AttributeError)
+ self.assertRaises(AttributeError, mock)
+
+ mock = Mock(side_effect=AttributeError('foo'))
+ self.assertRaises(AttributeError, mock)
+
+ def testBaseExceptionalSideEffect(self):
+ mock = Mock(side_effect=KeyboardInterrupt)
+ self.assertRaises(KeyboardInterrupt, mock)
+
+ mock = Mock(side_effect=KeyboardInterrupt('foo'))
+ self.assertRaises(KeyboardInterrupt, mock)
+
+
+if __name__ == '__main__':
+ unittest2.main()
diff --git a/tests/testmocksignature.py b/tests/testmocksignature.py
index d4fb7ac..e2a7850 100644
--- a/tests/testmocksignature.py
+++ b/tests/testmocksignature.py
@@ -16,34 +16,34 @@ class TestMockSignature(unittest2.TestCase):
def f(a):
pass
mock = Mock()
-
+
f2 = mocksignature(f, mock)
self.assertIs(f2.mock, mock)
-
+
self.assertRaises(TypeError, f2)
mock.return_value = 3
self.assertEqual(f2('foo'), 3)
mock.assert_called_with('foo')
f2.mock.assert_called_with('foo')
-
+
def testFunctionWithoutExplicitMock(self):
def f(a):
pass
-
+
f2 = mocksignature(f)
self.assertIsInstance(f2.mock, Mock)
-
+
self.assertRaises(TypeError, f2)
f2.mock.return_value = 3
self.assertEqual(f2('foo'), 3)
f2.mock.assert_called_with('foo')
-
-
+
+
def testMethod(self):
class Foo(object):
def method(self, a, b):
pass
-
+
f = Foo()
mock = Mock()
mock.return_value = 3
@@ -60,67 +60,67 @@ class TestMockSignature(unittest2.TestCase):
f2(3)
mock.assert_called_with(3, None)
mock.reset_mock()
-
+
f2(1, 7)
mock.assert_called_with(1, 7)
mock.reset_mock()
-
+
f2(b=1, a=7)
mock.assert_called_with(7, 1)
mock.reset_mock()
-
+
a = object()
def f(a=a):
pass
f2 = mocksignature(f, mock)
f2()
mock.assert_called_with(a)
-
+
def testIntrospection(self):
def f(a, *args, **kwargs):
pass
f2 = mocksignature(f, f)
self.assertEqual(inspect.getargspec(f), inspect.getargspec(f2))
-
+
def f(a, b=None, c=3, d=object()):
pass
f2 = mocksignature(f, f)
self.assertEqual(inspect.getargspec(f), inspect.getargspec(f2))
-
-
+
+
def testFunctionWithVarArgsAndKwargs(self):
def f(a, b=None, *args, **kwargs):
return (a, b, args, kwargs)
f2 = mocksignature(f, f)
self.assertEqual(f2(3, 4, 5, x=6, y=9), (3, 4, (5,), {'x': 6, 'y': 9}))
self.assertEqual(f2(3, x=6, y=9, b='a'), (3, 'a', (), {'x': 6, 'y': 9}))
-
-
+
+
def testMockSignatureWithPatch(self):
mock = Mock()
-
+
def f(a, b, c):
pass
mock.f = f
-
+
@apply
@patch.object(mock, 'f', mocksignature=True)
def test(mock_f):
self.assertRaises(TypeError, mock.f, 3, 4)
self.assertRaises(TypeError, mock.f, 3, 4, 5, 6)
mock.f(1, 2, 3)
-
+
mock_f.assert_called_with(1, 2, 3)
mock.f.mock.assert_called_with(1, 2, 3)
-
+
@apply
@patch('tests.support.SomeClass.wibble', mocksignature=True)
def test(mock_wibble):
from tests.support import SomeClass
-
+
instance = SomeClass()
self.assertRaises(TypeError, instance.wibble, 1)
instance.wibble()
-
+
mock_wibble.assert_called_with(instance)
- instance.wibble.mock.assert_called_with(instance)
+ instance.wibble.mock.assert_called_with(instance) \ No newline at end of file
diff --git a/tests/testpatch.py b/tests/testpatch.py
index 258c0a9..048d621 100644
--- a/tests/testpatch.py
+++ b/tests/testpatch.py
@@ -1,603 +1,602 @@
-# Copyright (C) 2007-2010 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-import os
-import warnings
-
-from tests.support import unittest2, apply, inPy3k, SomeClass, with_available
-
-if with_available:
- from tests.support_with import examine_warnings
-
-from mock import Mock, patch, patch_object, sentinel
-
-if not inPy3k:
- builtin_string = '__builtin__'
-else:
- builtin_string = 'builtins'
-
-
-# for use in the test
-something = sentinel.Something
-something_else = sentinel.SomethingElse
-
-
-class Container(object):
- def __init__(self):
- self.values = {}
-
- def __getitem__(self, name):
- return self.values[name]
-
- def __setitem__(self, name, value):
- self.values[name] = value
-
- def __delitem__(self, name):
- del self.values[name]
-
- def __iter__(self):
- return iter(self.values)
-
-
-class PatchTest(unittest2.TestCase):
-
- def testSinglePatchObject(self):
- class Something(object):
- attribute = sentinel.Original
-
- @apply
- @patch.object(Something, 'attribute', sentinel.Patched)
- def test():
- self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
-
- self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
-
-
- def testPatchObjectWithNone(self):
- class Something(object):
- attribute = sentinel.Original
-
- @apply
- @patch.object(Something, 'attribute', None)
- def test():
- self.assertIsNone(Something.attribute, "unpatched")
-
- self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
-
-
- def testMultiplePatchObject(self):
- class Something(object):
- attribute = sentinel.Original
- next_attribute = sentinel.Original2
-
- @apply
- @patch.object(Something, 'attribute', sentinel.Patched)
- @patch.object(Something, 'next_attribute', sentinel.Patched2)
- def test():
- self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
- self.assertEqual(Something.next_attribute, sentinel.Patched2, "unpatched")
-
- self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
- self.assertEqual(Something.next_attribute, sentinel.Original2, "patch not restored")
-
-
- def testObjectLookupIsQuiteLazy(self):
- global something
- original = something
- @patch('tests.testpatch.something', sentinel.Something2)
- def test():
- pass
-
- try:
- something = sentinel.replacement_value
- test()
- self.assertEqual(something, sentinel.replacement_value)
- finally:
- something = original
-
-
- def testPatch(self):
- import __main__
- __main__.something = sentinel.Something
-
- @apply
- @patch('__main__.something', sentinel.Something2)
- def test():
- self.assertEqual(__main__.something, sentinel.Something2, "unpatched")
-
- self.assertEqual(__main__.something, sentinel.Something, "patch not restored")
-
- import tests.testpatch as PTModule
-
- @patch('tests.testpatch.something', sentinel.Something2)
- @patch('tests.testpatch.something_else', sentinel.SomethingElse)
- def test():
- self.assertEqual(PTModule.something, sentinel.Something2, "unpatched")
- self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "unpatched")
-
- self.assertEqual(PTModule.something, sentinel.Something, "patch not restored")
- self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "patch not restored")
-
- # Test the patching and restoring works a second time
- test()
-
- self.assertEqual(PTModule.something, sentinel.Something, "patch not restored")
- self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "patch not restored")
-
- mock = Mock()
- mock.return_value = sentinel.Handle
- @patch('%s.open' % builtin_string, mock)
- def test():
- self.assertEqual(open('filename', 'r'), sentinel.Handle, "open not patched")
- test()
- test()
-
- self.assertNotEquals(open, mock, "patch not restored")
-
-
- def testPatchClassAttribute(self):
- import tests.testpatch as PTModule
-
- @patch('tests.testpatch.SomeClass.class_attribute', sentinel.ClassAttribute)
- def test():
- self.assertEqual(PTModule.SomeClass.class_attribute, sentinel.ClassAttribute, "unpatched")
- test()
-
- self.assertIsNone(PTModule.SomeClass.class_attribute, "patch not restored")
-
-
- def testPatchObjectWithDefaultMock(self):
- class Test(object):
- something = sentinel.Original
- something2 = sentinel.Original2
-
- @apply
- @patch.object(Test, 'something')
- def test(mock):
- self.assertEqual(mock, Test.something, "Mock not passed into test function")
- self.assertTrue(isinstance(mock, Mock),
- "patch with two arguments did not create a mock")
-
- @patch.object(Test, 'something')
- @patch.object(Test, 'something2')
- def test(this1, this2, mock1, mock2):
- self.assertEqual(this1, sentinel.this1, "Patched function didn't receive initial argument")
- self.assertEqual(this2, sentinel.this2, "Patched function didn't receive second argument")
- self.assertEqual(mock1, Test.something2, "Mock not passed into test function")
- self.assertEqual(mock2, Test.something, "Second Mock not passed into test function")
- self.assertTrue(isinstance(mock2, Mock),
- "patch with two arguments did not create a mock")
- self.assertTrue(isinstance(mock2, Mock),
- "patch with two arguments did not create a mock")
-
-
- # A hack to test that new mocks are passed the second time
- self.assertNotEquals(outerMock1, mock1, "unexpected value for mock1")
- self.assertNotEquals(outerMock2, mock2, "unexpected value for mock1")
- return mock1, mock2
-
- outerMock1 = None
- outerMock2 = None
- outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2)
-
- # Test that executing a second time creates new mocks
- test(sentinel.this1, sentinel.this2)
-
-
- def testPatchWithSpec(self):
- @patch('tests.testpatch.SomeClass', spec=SomeClass)
- def test(MockSomeClass):
- self.assertEqual(SomeClass, MockSomeClass)
- self.assertTrue(isinstance(SomeClass.wibble, Mock))
- self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
-
- test()
-
-
- def testPatchObjectWithSpec(self):
- @patch.object(SomeClass, 'class_attribute', spec=SomeClass)
- def test(MockAttribute):
- self.assertEqual(SomeClass.class_attribute, MockAttribute)
- self.assertTrue(isinstance(SomeClass.class_attribute.wibble, Mock))
- self.assertRaises(AttributeError, lambda: SomeClass.class_attribute.not_wibble)
-
- test()
-
-
- def testPatchWithSpecAsList(self):
- @patch('tests.testpatch.SomeClass', spec=['wibble'])
- def test(MockSomeClass):
- self.assertEqual(SomeClass, MockSomeClass)
- self.assertTrue(isinstance(SomeClass.wibble, Mock))
- self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
-
- test()
-
-
- def testPatchObjectWithSpecAsList(self):
- @patch.object(SomeClass, 'class_attribute', spec=['wibble'])
- def test(MockAttribute):
- self.assertEqual(SomeClass.class_attribute, MockAttribute)
- self.assertTrue(isinstance(SomeClass.class_attribute.wibble, Mock))
- self.assertRaises(AttributeError, lambda: SomeClass.class_attribute.not_wibble)
-
- test()
-
-
- def testNestedPatchWithSpecAsList(self):
- # regression test for nested decorators
- @patch('%s.open' % builtin_string)
- @patch('tests.testpatch.SomeClass', spec=['wibble'])
- def test(MockSomeClass, MockOpen):
- self.assertEqual(SomeClass, MockSomeClass)
- self.assertTrue(isinstance(SomeClass.wibble, Mock))
- self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
-
-
- def testPatchWithSpecAsBoolean(self):
- @apply
- @patch('tests.testpatch.SomeClass', spec=True)
- def test(MockSomeClass):
- self.assertEqual(SomeClass, MockSomeClass)
- # Should not raise attribute error
- MockSomeClass.wibble
-
- self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
-
-
- def testPatchObjectWithSpecAsBoolean(self):
- from tests import testpatch
- @apply
- @patch.object(testpatch, 'SomeClass', spec=True)
- def test(MockSomeClass):
- self.assertEqual(SomeClass, MockSomeClass)
- # Should not raise attribute error
- MockSomeClass.wibble
-
- self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
-
-
- def testPatchClassActsWithSpecIsInherited(self):
- @apply
- @patch('tests.testpatch.SomeClass', spec=True)
- def test(MockSomeClass):
- instance = MockSomeClass()
- # Should not raise attribute error
- instance.wibble
-
- self.assertRaises(AttributeError, lambda: instance.not_wibble)
-
-
- def testPatchWithCreateMocksNonExistentAttributes(self):
- @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True)
- def test():
- self.assertEqual(frooble, sentinel.Frooble)
-
- test()
- self.assertRaises(NameError, lambda: frooble)
-
-
- def testPatchObjectWithCreateMocksNonExistentAttributes(self):
- @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True)
- def test():
- self.assertEqual(SomeClass.frooble, sentinel.Frooble)
-
- test()
- self.assertFalse(hasattr(SomeClass, 'frooble'))
-
-
- def testPatchWontCreateByDefault(self):
- try:
- @patch('%s.frooble' % builtin_string, sentinel.Frooble)
- def test():
- self.assertEqual(frooble, sentinel.Frooble)
-
- test()
- except AttributeError:
- pass
- else:
- self.fail('Patching non existent attributes should fail')
-
- self.assertRaises(NameError, lambda: frooble)
-
-
- def testPatchObjecWontCreateByDefault(self):
- try:
- @patch.object(SomeClass, 'frooble', sentinel.Frooble)
- def test():
- self.assertEqual(SomeClass.frooble, sentinel.Frooble)
-
- test()
- except AttributeError:
- pass
- else:
- self.fail('Patching non existent attributes should fail')
- self.assertFalse(hasattr(SomeClass, 'frooble'))
-
-
- def testPathWithStaticMethods(self):
- class Foo(object):
- @staticmethod
- def woot():
- return sentinel.Static
-
- @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched))
- def anonymous():
- self.assertEqual(Foo.woot(), sentinel.Patched)
- anonymous()
-
- self.assertEqual(Foo.woot(), sentinel.Static)
-
-
- def testPatchLocal(self):
- foo = sentinel.Foo
- @patch.object(sentinel, 'Foo', 'Foo')
- def anonymous():
- self.assertEqual(sentinel.Foo, 'Foo')
- anonymous()
-
- self.assertEqual(sentinel.Foo, foo)
-
-
- def testPatchSlots(self):
- class Foo(object):
- __slots__ = ('Foo',)
-
- foo = Foo()
- foo.Foo = sentinel.Foo
-
- @patch.object(foo, 'Foo', 'Foo')
- def anonymous():
- self.assertEqual(foo.Foo, 'Foo')
- anonymous()
-
- self.assertEqual(foo.Foo, sentinel.Foo)
-
- def testPatchObjectClassDecorator(self):
- class Something(object):
- attribute = sentinel.Original
-
- class Foo(object):
- def test_method(other_self):
- self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
- def not_test_method(other_self):
- self.assertEqual(Something.attribute, sentinel.Original, "non-test method patched")
- Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo)
-
- f = Foo()
- f.test_method()
- f.not_test_method()
-
- self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
-
-
- def testPatchClassDecorator(self):
- import __main__
- __main__.something = sentinel.Something
-
- class Something(object):
- attribute = sentinel.Original
-
- class Foo(object):
- def test_method(other_self, mock_something):
- self.assertEqual(__main__.something, mock_something, "unpatched")
- def not_test_method(other_self):
- self.assertEqual(__main__.something, sentinel.Something, "non-test method patched")
- Foo = patch('__main__.something')(Foo)
-
- f = Foo()
- f.test_method()
- f.not_test_method()
-
- self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
- self.assertEqual(__main__.something, sentinel.Something, "patch not restored")
-
- @unittest2.skipUnless(with_available, "test requires Python >= 2.5")
- def testPatchObjectDeprecation(self):
- # needed to enable the deprecation warnings
- warnings.simplefilter('default')
-
- @apply
- @examine_warnings
- def _examine_warnings(ws):
- patch_object(SomeClass, 'class_attribute', spec=SomeClass)
- warning = ws[0]
- self.assertIs(warning.category, DeprecationWarning)
-
- def testPatchObjectTwice(self):
- class Something(object):
- attribute = sentinel.Original
- next_attribute = sentinel.Original2
-
- @apply
- @patch.object(Something, 'attribute', sentinel.Patched)
- @patch.object(Something, 'attribute', sentinel.Patched)
- def test():
- self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
-
- self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
-
- def testPatchDict(self):
- foo = {'initial': object(), 'other': 'something'}
- original = foo.copy()
-
- @apply
- @patch.dict(foo)
- def test():
- foo['a'] = 3
- del foo['initial']
- foo['other'] = 'something else'
-
- self.assertEqual(foo, original)
-
- @apply
- @patch.dict(foo, {'a': 'b'})
- def test():
- self.assertEqual(len(foo), 3)
- self.assertEqual(foo['a'], 'b')
-
- self.assertEqual(foo, original)
-
- @apply
- @patch.dict(foo, [('a', 'b')])
- def test():
- self.assertEqual(len(foo), 3)
- self.assertEqual(foo['a'], 'b')
-
- self.assertEqual(foo, original)
-
- def testPatchDictWithContainerObject(self):
- foo = Container()
- foo['initial'] = object()
- foo['other'] = 'something'
-
- original = foo.values.copy()
-
- @apply
- @patch.dict(foo)
- def test():
- foo['a'] = 3
- del foo['initial']
- foo['other'] = 'something else'
-
- self.assertEqual(foo.values, original)
-
- @apply
- @patch.dict(foo, {'a': 'b'})
- def test():
- self.assertEqual(len(foo.values), 3)
- self.assertEqual(foo['a'], 'b')
-
- self.assertEqual(foo.values, original)
-
- def testPatchDictWithClear(self):
- foo = {'initial': object(), 'other': 'something'}
- original = foo.copy()
-
- @apply
- @patch.dict(foo, clear=True)
- def test():
- self.assertEqual(foo, {})
- foo['a'] = 3
- foo['other'] = 'something else'
-
- self.assertEqual(foo, original)
-
- @apply
- @patch.dict(foo, {'a': 'b'}, clear=True)
- def test():
- self.assertEqual(foo, {'a': 'b'})
-
- self.assertEqual(foo, original)
-
- @apply
- @patch.dict(foo, [('a', 'b')], clear=True)
- def test():
- self.assertEqual(foo, {'a': 'b'})
-
- self.assertEqual(foo, original)
-
-
- def testPatchDictWithContainerObjectAndClear(self):
- foo = Container()
- foo['initial'] = object()
- foo['other'] = 'something'
-
- original = foo.values.copy()
-
- @apply
- @patch.dict(foo, clear=True)
- def test():
- self.assertEqual(foo.values, {})
- foo['a'] = 3
- foo['other'] = 'something else'
-
- self.assertEqual(foo.values, original)
-
- @apply
- @patch.dict(foo, {'a': 'b'}, clear=True)
- def test():
- self.assertEqual(foo.values, {'a': 'b'})
-
- self.assertEqual(foo.values, original)
-
- def testNamePreserved(self):
- foo = {}
-
- @patch('tests.testpatch.SomeClass', object())
- @patch('tests.testpatch.SomeClass', object(), mocksignature=True)
- @patch.object(SomeClass, object())
- @patch.dict(foo)
- def some_name():
- pass
-
- self.assertEqual(some_name.__name__, 'some_name')
-
- def testPatchWithException(self):
- foo = {}
-
- @patch.dict(foo, {'a': 'b'})
- def test():
- raise NameError('Konrad')
- try:
- test()
- except NameError:
- pass
- else:
- self.fail('NameError not raised by test')
-
- self.assertEqual(foo, {})
-
- def testPatchDictWithString(self):
- @apply
- @patch.dict('os.environ', {'konrad_delong': 'some value'})
- def test():
- self.assertIn('konrad_delong', os.environ)
-
- def DONTtestPatchDescriptor(self):
- # would be some effort to fix this - we could special case the
- # builtin descriptors: classmethod, property, staticmethod
- class Nothing(object):
- foo = None
-
- class Something(object):
- foo = {}
-
- @patch.object(Nothing, 'foo', 2)
- @classmethod
- def klass(cls):
- self.assertIs(cls, Something)
-
- @patch.object(Nothing, 'foo', 2)
- @staticmethod
- def static(arg):
- return arg
-
- @patch.dict(foo)
- @classmethod
- def klass_dict(cls):
- self.assertIs(cls, Something)
-
- @patch.dict(foo)
- @staticmethod
- def static_dict(arg):
- return arg
-
- # these will raise exceptions if patching descriptors is broken
- self.assertEqual(Something.static('f00'), 'f00')
- Something.klass()
- self.assertEqual(Something.static_dict('f00'), 'f00')
- Something.klass_dict()
-
- something = Something()
- self.assertEqual(something.static('f00'), 'f00')
- something.klass()
- self.assertEqual(something.static_dict('f00'), 'f00')
- something.klass_dict()
-
-
-if __name__ == '__main__':
- unittest2.main()
-
- \ No newline at end of file
+# Copyright (C) 2007-2010 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+
+import os
+import warnings
+
+from tests.support import unittest2, apply, inPy3k, SomeClass, with_available
+
+if with_available:
+ from tests.support_with import examine_warnings
+
+from mock import Mock, patch, patch_object, sentinel
+
+if not inPy3k:
+ builtin_string = '__builtin__'
+else:
+ builtin_string = 'builtins'
+
+
+# for use in the test
+something = sentinel.Something
+something_else = sentinel.SomethingElse
+
+
+class Container(object):
+ def __init__(self):
+ self.values = {}
+
+ def __getitem__(self, name):
+ return self.values[name]
+
+ def __setitem__(self, name, value):
+ self.values[name] = value
+
+ def __delitem__(self, name):
+ del self.values[name]
+
+ def __iter__(self):
+ return iter(self.values)
+
+
+class PatchTest(unittest2.TestCase):
+
+ def testSinglePatchObject(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ @apply
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ def test():
+ self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
+
+ self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
+
+
+ def testPatchObjectWithNone(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ @apply
+ @patch.object(Something, 'attribute', None)
+ def test():
+ self.assertIsNone(Something.attribute, "unpatched")
+
+ self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
+
+
+ def testMultiplePatchObject(self):
+ class Something(object):
+ attribute = sentinel.Original
+ next_attribute = sentinel.Original2
+
+ @apply
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ @patch.object(Something, 'next_attribute', sentinel.Patched2)
+ def test():
+ self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
+ self.assertEqual(Something.next_attribute, sentinel.Patched2, "unpatched")
+
+ self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
+ self.assertEqual(Something.next_attribute, sentinel.Original2, "patch not restored")
+
+
+ def testObjectLookupIsQuiteLazy(self):
+ global something
+ original = something
+ @patch('tests.testpatch.something', sentinel.Something2)
+ def test():
+ pass
+
+ try:
+ something = sentinel.replacement_value
+ test()
+ self.assertEqual(something, sentinel.replacement_value)
+ finally:
+ something = original
+
+
+ def testPatch(self):
+ import __main__
+ __main__.something = sentinel.Something
+
+ @apply
+ @patch('__main__.something', sentinel.Something2)
+ def test():
+ self.assertEqual(__main__.something, sentinel.Something2, "unpatched")
+
+ self.assertEqual(__main__.something, sentinel.Something, "patch not restored")
+
+ import tests.testpatch as PTModule
+
+ @patch('tests.testpatch.something', sentinel.Something2)
+ @patch('tests.testpatch.something_else', sentinel.SomethingElse)
+ def test():
+ self.assertEqual(PTModule.something, sentinel.Something2, "unpatched")
+ self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "unpatched")
+
+ self.assertEqual(PTModule.something, sentinel.Something, "patch not restored")
+ self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "patch not restored")
+
+ # Test the patching and restoring works a second time
+ test()
+
+ self.assertEqual(PTModule.something, sentinel.Something, "patch not restored")
+ self.assertEqual(PTModule.something_else, sentinel.SomethingElse, "patch not restored")
+
+ mock = Mock()
+ mock.return_value = sentinel.Handle
+ @patch('%s.open' % builtin_string, mock)
+ def test():
+ self.assertEqual(open('filename', 'r'), sentinel.Handle, "open not patched")
+ test()
+ test()
+
+ self.assertNotEquals(open, mock, "patch not restored")
+
+
+ def testPatchClassAttribute(self):
+ import tests.testpatch as PTModule
+
+ @patch('tests.testpatch.SomeClass.class_attribute', sentinel.ClassAttribute)
+ def test():
+ self.assertEqual(PTModule.SomeClass.class_attribute, sentinel.ClassAttribute, "unpatched")
+ test()
+
+ self.assertIsNone(PTModule.SomeClass.class_attribute, "patch not restored")
+
+
+ def testPatchObjectWithDefaultMock(self):
+ class Test(object):
+ something = sentinel.Original
+ something2 = sentinel.Original2
+
+ @apply
+ @patch.object(Test, 'something')
+ def test(mock):
+ self.assertEqual(mock, Test.something, "Mock not passed into test function")
+ self.assertTrue(isinstance(mock, Mock),
+ "patch with two arguments did not create a mock")
+
+ @patch.object(Test, 'something')
+ @patch.object(Test, 'something2')
+ def test(this1, this2, mock1, mock2):
+ self.assertEqual(this1, sentinel.this1, "Patched function didn't receive initial argument")
+ self.assertEqual(this2, sentinel.this2, "Patched function didn't receive second argument")
+ self.assertEqual(mock1, Test.something2, "Mock not passed into test function")
+ self.assertEqual(mock2, Test.something, "Second Mock not passed into test function")
+ self.assertTrue(isinstance(mock2, Mock),
+ "patch with two arguments did not create a mock")
+ self.assertTrue(isinstance(mock2, Mock),
+ "patch with two arguments did not create a mock")
+
+
+ # A hack to test that new mocks are passed the second time
+ self.assertNotEquals(outerMock1, mock1, "unexpected value for mock1")
+ self.assertNotEquals(outerMock2, mock2, "unexpected value for mock1")
+ return mock1, mock2
+
+ outerMock1 = None
+ outerMock2 = None
+ outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2)
+
+ # Test that executing a second time creates new mocks
+ test(sentinel.this1, sentinel.this2)
+
+
+ def testPatchWithSpec(self):
+ @patch('tests.testpatch.SomeClass', spec=SomeClass)
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ self.assertTrue(isinstance(SomeClass.wibble, Mock))
+ self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
+
+ test()
+
+
+ def testPatchObjectWithSpec(self):
+ @patch.object(SomeClass, 'class_attribute', spec=SomeClass)
+ def test(MockAttribute):
+ self.assertEqual(SomeClass.class_attribute, MockAttribute)
+ self.assertTrue(isinstance(SomeClass.class_attribute.wibble, Mock))
+ self.assertRaises(AttributeError, lambda: SomeClass.class_attribute.not_wibble)
+
+ test()
+
+
+ def testPatchWithSpecAsList(self):
+ @patch('tests.testpatch.SomeClass', spec=['wibble'])
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ self.assertTrue(isinstance(SomeClass.wibble, Mock))
+ self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
+
+ test()
+
+
+ def testPatchObjectWithSpecAsList(self):
+ @patch.object(SomeClass, 'class_attribute', spec=['wibble'])
+ def test(MockAttribute):
+ self.assertEqual(SomeClass.class_attribute, MockAttribute)
+ self.assertTrue(isinstance(SomeClass.class_attribute.wibble, Mock))
+ self.assertRaises(AttributeError, lambda: SomeClass.class_attribute.not_wibble)
+
+ test()
+
+
+ def testNestedPatchWithSpecAsList(self):
+ # regression test for nested decorators
+ @patch('%s.open' % builtin_string)
+ @patch('tests.testpatch.SomeClass', spec=['wibble'])
+ def test(MockSomeClass, MockOpen):
+ self.assertEqual(SomeClass, MockSomeClass)
+ self.assertTrue(isinstance(SomeClass.wibble, Mock))
+ self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
+
+
+ def testPatchWithSpecAsBoolean(self):
+ @apply
+ @patch('tests.testpatch.SomeClass', spec=True)
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ # Should not raise attribute error
+ MockSomeClass.wibble
+
+ self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
+
+
+ def testPatchObjectWithSpecAsBoolean(self):
+ from tests import testpatch
+ @apply
+ @patch.object(testpatch, 'SomeClass', spec=True)
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ # Should not raise attribute error
+ MockSomeClass.wibble
+
+ self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
+
+
+ def testPatchClassActsWithSpecIsInherited(self):
+ @apply
+ @patch('tests.testpatch.SomeClass', spec=True)
+ def test(MockSomeClass):
+ instance = MockSomeClass()
+ # Should not raise attribute error
+ instance.wibble
+
+ self.assertRaises(AttributeError, lambda: instance.not_wibble)
+
+
+ def testPatchWithCreateMocksNonExistentAttributes(self):
+ @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True)
+ def test():
+ self.assertEqual(frooble, sentinel.Frooble)
+
+ test()
+ self.assertRaises(NameError, lambda: frooble)
+
+
+ def testPatchObjectWithCreateMocksNonExistentAttributes(self):
+ @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True)
+ def test():
+ self.assertEqual(SomeClass.frooble, sentinel.Frooble)
+
+ test()
+ self.assertFalse(hasattr(SomeClass, 'frooble'))
+
+
+ def testPatchWontCreateByDefault(self):
+ try:
+ @patch('%s.frooble' % builtin_string, sentinel.Frooble)
+ def test():
+ self.assertEqual(frooble, sentinel.Frooble)
+
+ test()
+ except AttributeError:
+ pass
+ else:
+ self.fail('Patching non existent attributes should fail')
+
+ self.assertRaises(NameError, lambda: frooble)
+
+
+ def testPatchObjecWontCreateByDefault(self):
+ try:
+ @patch.object(SomeClass, 'frooble', sentinel.Frooble)
+ def test():
+ self.assertEqual(SomeClass.frooble, sentinel.Frooble)
+
+ test()
+ except AttributeError:
+ pass
+ else:
+ self.fail('Patching non existent attributes should fail')
+ self.assertFalse(hasattr(SomeClass, 'frooble'))
+
+
+ def testPathWithStaticMethods(self):
+ class Foo(object):
+ @staticmethod
+ def woot():
+ return sentinel.Static
+
+ @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched))
+ def anonymous():
+ self.assertEqual(Foo.woot(), sentinel.Patched)
+ anonymous()
+
+ self.assertEqual(Foo.woot(), sentinel.Static)
+
+
+ def testPatchLocal(self):
+ foo = sentinel.Foo
+ @patch.object(sentinel, 'Foo', 'Foo')
+ def anonymous():
+ self.assertEqual(sentinel.Foo, 'Foo')
+ anonymous()
+
+ self.assertEqual(sentinel.Foo, foo)
+
+
+ def testPatchSlots(self):
+ class Foo(object):
+ __slots__ = ('Foo',)
+
+ foo = Foo()
+ foo.Foo = sentinel.Foo
+
+ @patch.object(foo, 'Foo', 'Foo')
+ def anonymous():
+ self.assertEqual(foo.Foo, 'Foo')
+ anonymous()
+
+ self.assertEqual(foo.Foo, sentinel.Foo)
+
+ def testPatchObjectClassDecorator(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ class Foo(object):
+ def test_method(other_self):
+ self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
+ def not_test_method(other_self):
+ self.assertEqual(Something.attribute, sentinel.Original, "non-test method patched")
+ Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo)
+
+ f = Foo()
+ f.test_method()
+ f.not_test_method()
+
+ self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
+
+
+ def testPatchClassDecorator(self):
+ import __main__
+ __main__.something = sentinel.Something
+
+ class Something(object):
+ attribute = sentinel.Original
+
+ class Foo(object):
+ def test_method(other_self, mock_something):
+ self.assertEqual(__main__.something, mock_something, "unpatched")
+ def not_test_method(other_self):
+ self.assertEqual(__main__.something, sentinel.Something, "non-test method patched")
+ Foo = patch('__main__.something')(Foo)
+
+ f = Foo()
+ f.test_method()
+ f.not_test_method()
+
+ self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
+ self.assertEqual(__main__.something, sentinel.Something, "patch not restored")
+
+ @unittest2.skipUnless(with_available, "test requires Python >= 2.5")
+ def testPatchObjectDeprecation(self):
+ # needed to enable the deprecation warnings
+ warnings.simplefilter('default')
+
+ @apply
+ @examine_warnings
+ def _examine_warnings(ws):
+ patch_object(SomeClass, 'class_attribute', spec=SomeClass)
+ warning = ws[0]
+ self.assertIs(warning.category, DeprecationWarning)
+
+ def testPatchObjectTwice(self):
+ class Something(object):
+ attribute = sentinel.Original
+ next_attribute = sentinel.Original2
+
+ @apply
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ def test():
+ self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
+
+ self.assertEqual(Something.attribute, sentinel.Original, "patch not restored")
+
+ def testPatchDict(self):
+ foo = {'initial': object(), 'other': 'something'}
+ original = foo.copy()
+
+ @apply
+ @patch.dict(foo)
+ def test():
+ foo['a'] = 3
+ del foo['initial']
+ foo['other'] = 'something else'
+
+ self.assertEqual(foo, original)
+
+ @apply
+ @patch.dict(foo, {'a': 'b'})
+ def test():
+ self.assertEqual(len(foo), 3)
+ self.assertEqual(foo['a'], 'b')
+
+ self.assertEqual(foo, original)
+
+ @apply
+ @patch.dict(foo, [('a', 'b')])
+ def test():
+ self.assertEqual(len(foo), 3)
+ self.assertEqual(foo['a'], 'b')
+
+ self.assertEqual(foo, original)
+
+ def testPatchDictWithContainerObject(self):
+ foo = Container()
+ foo['initial'] = object()
+ foo['other'] = 'something'
+
+ original = foo.values.copy()
+
+ @apply
+ @patch.dict(foo)
+ def test():
+ foo['a'] = 3
+ del foo['initial']
+ foo['other'] = 'something else'
+
+ self.assertEqual(foo.values, original)
+
+ @apply
+ @patch.dict(foo, {'a': 'b'})
+ def test():
+ self.assertEqual(len(foo.values), 3)
+ self.assertEqual(foo['a'], 'b')
+
+ self.assertEqual(foo.values, original)
+
+ def testPatchDictWithClear(self):
+ foo = {'initial': object(), 'other': 'something'}
+ original = foo.copy()
+
+ @apply
+ @patch.dict(foo, clear=True)
+ def test():
+ self.assertEqual(foo, {})
+ foo['a'] = 3
+ foo['other'] = 'something else'
+
+ self.assertEqual(foo, original)
+
+ @apply
+ @patch.dict(foo, {'a': 'b'}, clear=True)
+ def test():
+ self.assertEqual(foo, {'a': 'b'})
+
+ self.assertEqual(foo, original)
+
+ @apply
+ @patch.dict(foo, [('a', 'b')], clear=True)
+ def test():
+ self.assertEqual(foo, {'a': 'b'})
+
+ self.assertEqual(foo, original)
+
+
+ def testPatchDictWithContainerObjectAndClear(self):
+ foo = Container()
+ foo['initial'] = object()
+ foo['other'] = 'something'
+
+ original = foo.values.copy()
+
+ @apply
+ @patch.dict(foo, clear=True)
+ def test():
+ self.assertEqual(foo.values, {})
+ foo['a'] = 3
+ foo['other'] = 'something else'
+
+ self.assertEqual(foo.values, original)
+
+ @apply
+ @patch.dict(foo, {'a': 'b'}, clear=True)
+ def test():
+ self.assertEqual(foo.values, {'a': 'b'})
+
+ self.assertEqual(foo.values, original)
+
+ def testNamePreserved(self):
+ foo = {}
+
+ @patch('tests.testpatch.SomeClass', object())
+ @patch('tests.testpatch.SomeClass', object(), mocksignature=True)
+ @patch.object(SomeClass, object())
+ @patch.dict(foo)
+ def some_name():
+ pass
+
+ self.assertEqual(some_name.__name__, 'some_name')
+
+ def testPatchWithException(self):
+ foo = {}
+
+ @patch.dict(foo, {'a': 'b'})
+ def test():
+ raise NameError('Konrad')
+ try:
+ test()
+ except NameError:
+ pass
+ else:
+ self.fail('NameError not raised by test')
+
+ self.assertEqual(foo, {})
+
+ def testPatchDictWithString(self):
+ @apply
+ @patch.dict('os.environ', {'konrad_delong': 'some value'})
+ def test():
+ self.assertIn('konrad_delong', os.environ)
+
+ def DONTtestPatchDescriptor(self):
+ # would be some effort to fix this - we could special case the
+ # builtin descriptors: classmethod, property, staticmethod
+ class Nothing(object):
+ foo = None
+
+ class Something(object):
+ foo = {}
+
+ @patch.object(Nothing, 'foo', 2)
+ @classmethod
+ def klass(cls):
+ self.assertIs(cls, Something)
+
+ @patch.object(Nothing, 'foo', 2)
+ @staticmethod
+ def static(arg):
+ return arg
+
+ @patch.dict(foo)
+ @classmethod
+ def klass_dict(cls):
+ self.assertIs(cls, Something)
+
+ @patch.dict(foo)
+ @staticmethod
+ def static_dict(arg):
+ return arg
+
+ # these will raise exceptions if patching descriptors is broken
+ self.assertEqual(Something.static('f00'), 'f00')
+ Something.klass()
+ self.assertEqual(Something.static_dict('f00'), 'f00')
+ Something.klass_dict()
+
+ something = Something()
+ self.assertEqual(something.static('f00'), 'f00')
+ something.klass()
+ self.assertEqual(something.static_dict('f00'), 'f00')
+ something.klass_dict()
+
+
+if __name__ == '__main__':
+ unittest2.main()
+
diff --git a/tests/testsentinel.py b/tests/testsentinel.py
index d11bf49..4c355d7 100644
--- a/tests/testsentinel.py
+++ b/tests/testsentinel.py
@@ -1,31 +1,30 @@
-# Copyright (C) 2007-2010 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-from tests.support import unittest2
-
-from mock import sentinel, DEFAULT
-
-
-class SentinelTest(unittest2.TestCase):
-
- def testSentinels(self):
- self.assertEqual(sentinel.whatever, sentinel.whatever, 'sentinel not stored')
- self.assertNotEquals(sentinel.whatever, sentinel.whateverelse, 'sentinel should be unique')
-
-
- def testSentinelName(self):
- self.assertEqual(str(sentinel.whatever), '<SentinelObject "whatever">', 'sentinel name incorrect')
-
-
- def testDEFAULT(self):
- self.assertTrue(DEFAULT is sentinel.DEFAULT)
-
- def testBases(self):
- # If this doesn't raise an AttributeError then help(mock) is broken
- self.assertRaises(AttributeError, lambda: sentinel.__bases__)
-
-
-if __name__ == '__main__':
- unittest2.main()
-
+# Copyright (C) 2007-2010 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+
+from tests.support import unittest2
+
+from mock import sentinel, DEFAULT
+
+
+class SentinelTest(unittest2.TestCase):
+
+ def testSentinels(self):
+ self.assertEqual(sentinel.whatever, sentinel.whatever, 'sentinel not stored')
+ self.assertNotEquals(sentinel.whatever, sentinel.whateverelse, 'sentinel should be unique')
+
+
+ def testSentinelName(self):
+ self.assertEqual(str(sentinel.whatever), '<SentinelObject "whatever">', 'sentinel name incorrect')
+
+
+ def testDEFAULT(self):
+ self.assertTrue(DEFAULT is sentinel.DEFAULT)
+
+ def testBases(self):
+ # If this doesn't raise an AttributeError then help(mock) is broken
+ self.assertRaises(AttributeError, lambda: sentinel.__bases__)
+
+
+if __name__ == '__main__':
+ unittest2.main()
diff --git a/tests/testwith.py b/tests/testwith.py
index baecd35..411cdbf 100644
--- a/tests/testwith.py
+++ b/tests/testwith.py
@@ -18,13 +18,13 @@ class WithTest(unittest2.TestCase):
def testWithStatement(self):
with patch('tests.testwith.something', sentinel.Something2):
- self.assertEqual(something, sentinel.Something2, "unpatched")
+ self.assertEqual(something, sentinel.Something2, "unpatched")
self.assertEqual(something, sentinel.Something)
-
+
def testWithStatementException(self):
try:
with patch('tests.testwith.something', sentinel.Something2):
- self.assertEqual(something, sentinel.Something2, "unpatched")
+ self.assertEqual(something, sentinel.Something2, "unpatched")
raise Exception('pow')
except Exception:
pass
@@ -35,7 +35,7 @@ class WithTest(unittest2.TestCase):
def testWithStatementAs(self):
with patch('tests.testwith.something') as mock_something:
- self.assertEqual(something, mock_something, "unpatched")
+ self.assertEqual(something, mock_something, "unpatched")
self.assertTrue(isinstance(mock_something, Mock), "patching wrong type")
self.assertEqual(something, sentinel.Something)
@@ -44,14 +44,14 @@ class WithTest(unittest2.TestCase):
mock = Mock()
original = mock.something
with patch.object(mock, 'something'):
- self.assertNotEquals(mock.something, original, "unpatched")
+ self.assertNotEquals(mock.something, original, "unpatched")
self.assertEqual(mock.something, original)
def testWithStatementNested(self):
with catch_warnings(record=True):
# nested is deprecated in Python 2.7
- with nested(patch('tests.testwith.something'),
+ with nested(patch('tests.testwith.something'),
patch('tests.testwith.something_else')) as (mock_something, mock_something_else):
self.assertEqual(something, mock_something, "unpatched")
self.assertEqual(something_else, mock_something_else, "unpatched")
@@ -61,26 +61,26 @@ class WithTest(unittest2.TestCase):
def testWithStatementSpecified(self):
with patch('tests.testwith.something', sentinel.Patched) as mock_something:
- self.assertEqual(something, mock_something, "unpatched")
- self.assertEqual(mock_something, sentinel.Patched, "wrong patch")
+ self.assertEqual(something, mock_something, "unpatched")
+ self.assertEqual(mock_something, sentinel.Patched, "wrong patch")
self.assertEqual(something, sentinel.Something)
-
+
def testContextManagerMocking(self):
mock = Mock()
mock.__enter__ = Mock()
mock.__exit__ = Mock()
mock.__exit__.return_value = False
-
+
with mock as m:
self.assertEqual(m, mock.__enter__.return_value)
mock.__enter__.assert_called_with()
mock.__exit__.assert_called_with(None, None, None)
-
+
def testContextManagerWithMagicMock(self):
mock = MagicMock()
-
+
with self.assertRaises(TypeError):
with mock:
'foo' + 3
@@ -102,10 +102,10 @@ class WithTest(unittest2.TestCase):
def testWithStatementImbricated(self):
with patch('tests.testwith.something') as mock_something:
self.assertEqual(something, mock_something, "unpatched")
-
- with patch('tests.testwith.something_else') as mock_something_else:
+
+ with patch('tests.testwith.something_else') as mock_something_else:
self.assertEqual(something_else, mock_something_else, "unpatched")
-
+
self.assertEqual(something, sentinel.Something)
self.assertEqual(something_else, sentinel.SomethingElse)
@@ -114,15 +114,14 @@ class WithTest(unittest2.TestCase):
with patch.dict(foo, {'a': 'b'}):
self.assertEqual(foo, {'a': 'b'})
self.assertEqual(foo, {})
-
+
with self.assertRaises(NameError):
with patch.dict(foo, {'a': 'b'}):
self.assertEqual(foo, {'a': 'b'})
raise NameError('Konrad')
-
+
self.assertEqual(foo, {})
if __name__ == '__main__':
unittest2.main()
-