MiniMock-1.2.7/000755 000765 000024 00000000000 11623500114 013117 5ustar00jabstaff000000 000000 MiniMock-1.2.7/docs/000755 000765 000024 00000000000 11623500114 014047 5ustar00jabstaff000000 000000 MiniMock-1.2.7/MANIFEST.in000644 000765 000024 00000000031 11256764727 014677 0ustar00jabstaff000000 000000 recursive-include docs * MiniMock-1.2.7/MiniMock.egg-info/000755 000765 000024 00000000000 11623500114 016317 5ustar00jabstaff000000 000000 MiniMock-1.2.7/minimock.py000644 000765 000024 00000047643 11611343473 015327 0ustar00jabstaff000000 000000 # (c) 2006-2009 Ian Bicking, Mike Beachy, and contributors # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php r""" minimock is a simple library for doing Mock objects with doctest. When using doctest, mock objects can be very simple. Here's an example of something we might test, a simple email sender:: >>> import smtplib >>> def send_email(from_addr, to_addr, subject, body): ... conn = smtplib.SMTP('localhost') ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % ( ... to_addr, from_addr, subject, body) ... conn.sendmail(from_addr, [to_addr], msg) ... conn.quit() Now we want to make a mock ``smtplib.SMTP`` object. We'll have to inject our mock into the ``smtplib`` module:: >>> smtplib.SMTP = Mock('smtplib.SMTP') >>> smtplib.SMTP.mock_returns = Mock('smtp_connection') Now we do the test:: >>> send_email('ianb@colorstudy.com', 'joe@example.com', ... 'Hi there!', 'How is it going?') Called smtplib.SMTP('localhost') Called smtp_connection.sendmail( 'ianb@colorstudy.com', ['joe@example.com'], 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?') Called smtp_connection.quit() Voila! We've tested implicitly that no unexpected methods were called on the object. We've also tested the arguments that the mock object got. We've provided fake return calls (for the ``smtplib.SMTP()`` constructor). These are all the core parts of a mock library. The implementation is simple because most of the work is done by doctest. """ __all__ = ["mock", "restore", "Mock", "TraceTracker", "assert_same_trace"] import __builtin__ import sys import inspect import doctest import re import textwrap try: from cStringIO import StringIO except ImportError: from StringIO import StringIO # A list of mocked objects. Each item is a tuple of (original object, # namespace dict, object name, and a list of object attributes). # mocked = [] def lookup_by_name(name, nsdicts): """ Look up an object by name from a sequence of namespace dictionaries. Returns a tuple of (nsdict, obj_name, attrs); nsdict is the namespace dictionary the name was found in, obj_name is the name of the base object the name is bound to, and the attrs list is the chain of attributes of the object that completes the name. >>> import os >>> nsdict, obj_name, attrs = lookup_by_name("os.path.isdir", ... (locals(),)) >>> obj_name, attrs ('os', ['path', 'isdir']) >>> getattr(getattr(nsdict[obj_name], attrs[0]), attrs[1]) >>> lookup_by_name("os.monkey", (locals(),)) Traceback (most recent call last): ... NameError: name 'os.monkey' is not defined """ for nsdict in nsdicts: attrs = name.split(".") names = [] while attrs: names.append(attrs.pop(0)) obj_name = ".".join(names) if obj_name in nsdict: attr_copy = attrs[:] tmp = nsdict[obj_name] try: while attr_copy: tmp = getattr(tmp, attr_copy.pop(0)) except AttributeError: pass else: return nsdict, obj_name, attrs raise NameError("name '%s' is not defined" % name) def mock(name, nsdicts=None, mock_obj=None, **kw): """ Mock the named object, placing a Mock instance in the correct namespace dictionary. If no iterable of namespace dicts is provided, use introspection to get the locals and globals of the caller of this function, as well as __builtin__.__dict__ to allow mocking built-ins. All additional keyword args are passed on to the Mock object initializer. An example of how os.path.isfile is replaced:: >>> import os >>> os.path.isfile >>> isfile_id = id(os.path.isfile) >>> mock("os.path.isfile", returns=True) >>> os.path.isfile >>> os.path.isfile("/foo/bar/baz") Called os.path.isfile('/foo/bar/baz') True >>> mock_id = id(os.path.isfile) >>> mock_id != isfile_id True A second mock object will replace the first, but the original object will be the one replaced with the replace() function. >>> mock("os.path.isfile", returns=False) >>> mock_id != id(os.path.isfile) True >>> restore() >>> os.path.isfile >>> isfile_id == id(os.path.isfile) True Test mocking a built-in function:: >>> mock("raw_input", returns="okay") >>> raw_input() Called raw_input() 'okay' >>> restore() Test mocking and restoring a classmethod and staticmethod:: >>> class Test(object): ... @classmethod ... def cm(cls): ... return 'cm' ... @staticmethod ... def sm(): ... return 'sm' >>> mock('Test.cm', returns='mocked') >>> mock('Test.sm', returns='mocked') >>> Test.cm() Called Test.cm() 'mocked' >>> Test.sm() Called Test.sm() 'mocked' >>> restore() >>> Test.cm() 'cm' >>> Test.sm() 'sm' Test mocking a proxy object:: >>> class Proxy(object): ... def __init__(self, obj): ... self._obj = obj ... def __getattr__(self, name): ... return getattr(self._obj, name) >>> import os >>> os = Proxy(os) >>> os.path.isfile >>> mock('os.path.isfile') >>> os.path.isfile >>> restore() """ if nsdicts is None: stack = inspect.stack() try: # stack[1][0] is the frame object of the caller to this function globals_ = stack[1][0].f_globals locals_ = stack[1][0].f_locals nsdicts = (locals_, globals_, __builtin__.__dict__) finally: del(stack) if mock_obj is None: mock_obj = Mock(name, **kw) nsdict, obj_name, attrs = lookup_by_name(name, nsdicts) # Get the original object and replace it with the mock object. tmp = nsdict[obj_name] # if run from a doctest, nsdict may point to a *copy* of the # global namespace, so instead use tmp.func_globals if present. # we use isinstance(gettattr(...), dict) rather than hasattr # because if tmp is itself a mock object, tmp.func_globals will # return another mock object if isinstance(getattr(tmp, 'func_globals', None), dict): nsdict = tmp.func_globals if not attrs: original = tmp nsdict[obj_name] = mock_obj else: for attr in attrs[:-1]: try: tmp = tmp.__dict__[attr] except KeyError: tmp = getattr(tmp, attr) try: original = tmp.__dict__[attrs[-1]] except KeyError: original = getattr(tmp, attrs[-1]) setattr(tmp, attrs[-1], mock_obj) mocked.append((original, nsdict, obj_name, attrs)) def restore(): """ Restore all mocked objects. """ global mocked # Restore the objects in the reverse order of their mocking to assure # the original state is retrieved. while mocked: original, nsdict, name, attrs = mocked.pop() if not attrs: nsdict[name] = original else: tmp = nsdict[name] for attr in attrs[:-1]: try: tmp = tmp.__dict__[attr] except KeyError: tmp = getattr(tmp, attr) setattr(tmp, attrs[-1], original) def assert_same_trace(tracker, want): r""" Check that the mock objects using ``tracker`` have been used as expected. :param tracker: a :class:`TraceTracker` instance :param want: the expected :class:`Printer` output :type want: string :raises: :exc:`AssertionError` if the expected and observed outputs don't match Example:: >>> tt = TraceTracker() >>> m = Mock('mock_obj', tracker=tt) >>> m.some_meth('dummy argument') >>> assert_same_trace(tt, ... "Called mock_obj.some_meth('dummy argument')\n") >>> assert_same_trace(tt, "Non-matching trace") Traceback (most recent call last): ... AssertionError... """ assert tracker.check(want), tracker.diff(want) class AbstractTracker(object): def __init__(self, *args, **kw): raise NotImplementedError def call(self, *args, **kw): raise NotImplementedError def set(self, *args, **kw): raise NotImplementedError class Printer(AbstractTracker): """Prints all calls to the file it's instantiated with. Can take any object that implements `write'. """ def __init__(self, file): self.file = file def call(self, func_name, *args, **kw): parts = [repr(a) for a in args] parts.extend( '%s=%r' % (items) for items in sorted(kw.items())) msg = 'Called %s(%s)' % (func_name, ', '.join(parts)) if len(msg) > 80: msg = 'Called %s(\n %s)' % ( func_name, ',\n '.join(parts)) print >> self.file, msg def set(self, obj_name, attr, value): """ >>> z = Mock('z', show_attrs=True) >>> z.a = 2 Set z.a = 2 """ print >> self.file, 'Set %s.%s = %r' % (obj_name, attr, value) class TraceTracker(Printer): """ :class:`AbstractTracker` implementation for using MiniMock in non- :mod:`doctest` tests. Follows the pattern of recording minimocked object usage as strings, then using the facilities of :mod:`doctest` to assert the correctness of these usage strings. """ def __init__(self, *args, **kw): self.out = StringIO() super(TraceTracker, self).__init__(self.out, *args, **kw) self.checker = MinimockOutputChecker() self.options = doctest.ELLIPSIS self.options |= doctest.NORMALIZE_INDENTATION self.options |= doctest.NORMALIZE_FUNCTION_PARAMETERS self.options |= doctest.REPORT_UDIFF def check(self, want): r""" Compare observed MiniMock usage with that which we expected. :param want: the :class:`Printer` output that results from expected usage of mocked objects :type want: string :rtype: a ``True`` value if the check passed, ``False`` otherwise Example:: >>> tt = TraceTracker() >>> m = Mock('mock_obj', tracker=tt) >>> m.some_meth('arg1') >>> tt.check("Called mock_obj.some_meth('arg1')") True >>> tt.clear() >>> m.some_meth('arg2') >>> tt.check("does not match") False """ return self.checker.check_output(want, self.dump(), optionflags=self.options) def diff(self, want): r""" Analyse differences between observed MiniMock usage and that which we expected, if any. :param want: the :class:`Printer` output that results from expected usage of mocked objects :type want: string :rtype: a string summary of differences between the observed usage and the ``want`` parameter Example:: >>> tt = TraceTracker() >>> m = Mock('mock_obj', tracker=tt) >>> m.some_meth('dummy argument') >>> tt.diff("does not match") "Expected:\n does not match\nGot:\n Called mock_obj.some_meth('dummy argument')\n" >>> tt.diff("Called mock_obj.some_meth('dummy argument')") '' """ if self.check(want): # doctest's output_difference always returns a diff, even if # there's no difference: short circuit that feature. return '' else: return self.checker.output_difference(doctest.Example("", want), self.dump(), optionflags=self.options) def dump(self): r""" Return the MiniMock object usage so far. Example:: >>> tt = TraceTracker() >>> m = Mock('mock_obj', tracker=tt) >>> m.some_meth('dummy argument') >>> tt.dump() "Called mock_obj.some_meth('dummy argument')\n" """ return self.out.getvalue() def clear(self): """Clear the MiniMock object usage that has been tracked so far. """ self.out.truncate(0) def normalize_function_parameters(text): r""" Return a version of ``text`` with function parameters normalized. The normalisations performed are: * Remove any whitespace sequence between an opening parenthesis '(' and a subsequent non-whitespace character. * Remove any whitespace sequence between a non-whitespace character and a closing parenthesis ')'. * Ensure a comma ',' and a subsequent non-whitespace character are separated by a single space ' '. Example:: >>> tt = TraceTracker() >>> foo = Mock("foo", tracker=tt) >>> expect_mock_output = '''\ ... Called foo.bar('baz') ... ''' >>> foo.bar('baz') >>> tt.check(expect_mock_output) True >>> tt.clear() >>> expect_mock_output = '''\ ... Called foo.bar( ... 'baz') ... ''' >>> foo.bar('baz') >>> tt.check(expect_mock_output) True """ normalized_text = text normalize_map = { re.compile(r"\(\s+(\S)"): r"(\1", re.compile(r"(\S)\s+\)"): r"\1)", re.compile(r",\s*(\S)"): r", \1", } for search_pattern, replace_pattern in normalize_map.items(): normalized_text = re.sub( search_pattern, replace_pattern, normalized_text) return normalized_text doctest.NORMALIZE_INDENTATION = ( doctest.register_optionflag('NORMALIZE_INDENTATION')) doctest.NORMALIZE_FUNCTION_PARAMETERS = ( doctest.register_optionflag('NORMALIZE_FUNCTION_PARAMETERS')) class MinimockOutputChecker(doctest.OutputChecker, object): """Class for matching output of MiniMock objects against expectations. """ def check_output(self, want, got, optionflags): if (optionflags & doctest.NORMALIZE_INDENTATION): want = textwrap.dedent(want).rstrip() got = textwrap.dedent(got).rstrip() if (optionflags & doctest.NORMALIZE_FUNCTION_PARAMETERS): want = normalize_function_parameters(want) got = normalize_function_parameters(got) output_match = super(MinimockOutputChecker, self).check_output( want, got, optionflags) return output_match check_output.__doc__ = doctest.OutputChecker.check_output.__doc__ class _DefaultTracker(object): def __repr__(self): return '(default tracker)' DefaultTracker = _DefaultTracker() del _DefaultTracker class Mock(object): def __init__(self, name, returns=None, returns_iter=None, returns_func=None, raises=None, show_attrs=False, tracker=DefaultTracker, **kw): _obsetattr = object.__setattr__ _obsetattr(self, 'mock_name', name) _obsetattr(self, 'mock_returns', returns) if returns_iter is not None: returns_iter = iter(returns_iter) _obsetattr(self, 'mock_returns_iter', returns_iter) _obsetattr(self, 'mock_returns_func', returns_func) _obsetattr(self, 'mock_raises', raises) _obsetattr(self, 'mock_attrs', kw) _obsetattr(self, 'mock_show_attrs', show_attrs) if tracker is DefaultTracker: tracker = Printer(sys.stdout) _obsetattr(self, 'mock_tracker', tracker) def __repr__(self): return '' % (hex(id(self)), self.mock_name) def __call__(self, *args, **kw): if self.mock_tracker is not None: self.mock_tracker.call(self.mock_name, *args, **kw) return self._mock_return(*args, **kw) def _mock_return(self, *args, **kw): if self.mock_raises is not None: raise self.mock_raises elif self.mock_returns is not None: return self.mock_returns elif self.mock_returns_iter is not None: try: return self.mock_returns_iter.next() except StopIteration: raise Exception("No more mock return values are present.") elif self.mock_returns_func is not None: return self.mock_returns_func(*args, **kw) else: return None def __getattr__(self, attr): if attr not in self.mock_attrs: if self.mock_name: new_name = self.mock_name + '.' + attr else: new_name = attr self.mock_attrs[attr] = Mock(new_name, show_attrs=self.mock_show_attrs, tracker=self.mock_tracker) return self.mock_attrs[attr] def __setattr__(self, attr, value): if attr in frozenset(( 'mock_raises', 'mock_returns', 'mock_returns_func', 'mock_returns_iter', 'mock_tracker', 'mock_show_attrs', )): if attr == 'mock_returns_iter' and value is not None: value = iter(value) object.__setattr__(self, attr, value) else: if self.mock_show_attrs and self.mock_tracker is not None: self.mock_tracker.set(self.mock_name, attr, value) self.mock_attrs[attr] = value __test__ = { "Mock" : r""" Test setting various "mock_" attributes on an existing Mock object. >>> m = Mock('mock_obj', tracker=None) >>> m.mock_returns = 42 >>> m() 42 >>> m.mock_returns = None >>> m.mock_returns_func = lambda x: x*x >>> m(3) 9 >>> m.mock_returns_func = None >>> m.mock_returns_iter = [True, False] >>> m() True >>> m() False >>> m.mock_returns_iter = None >>> m.mock_raises = ValueError >>> try: ... m() ... except ValueError: ... pass ... else: ... raise AssertionError('m() should have raised ValueError') >>> m.mock_tracker = Printer(sys.stdout) >>> m.mock_show_attrs = True >>> m.a = 2 Set mock_obj.a = 2 """, "mock" : r""" An additional test for mocking a function accessed directly (i.e. not via object attributes). >>> import os >>> rename = os.rename >>> orig_id = id(rename) >>> mock("rename") >>> mock_id = id(rename) >>> mock("rename") >>> mock_id != id(rename) True >>> restore() >>> orig_id == id(rename) == id(os.rename) True The example from the module docstring, done with the mock/restore functions. >>> import smtplib >>> def send_email(from_addr, to_addr, subject, body): ... conn = smtplib.SMTP('localhost') ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % ( ... to_addr, from_addr, subject, body) ... conn.sendmail(from_addr, [to_addr], msg) ... conn.quit() >>> mock("smtplib.SMTP", returns=Mock('smtp_connection')) >>> send_email('ianb@colorstudy.com', 'joe@example.com', ... 'Hi there!', 'How is it going?') Called smtplib.SMTP('localhost') Called smtp_connection.sendmail( 'ianb@colorstudy.com', ['joe@example.com'], 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?') Called smtp_connection.quit() >>> restore() """, } if __name__ == '__main__': import doctest doctest.testmod(optionflags=doctest.ELLIPSIS) MiniMock-1.2.7/PKG-INFO000644 000765 000024 00000022024 11623500114 014214 0ustar00jabstaff000000 000000 Metadata-Version: 1.0 Name: MiniMock Version: 1.2.7 Summary: The simplest possible mock library Home-page: http://pypi.python.org/pypi/MiniMock Author: Ian Bicking Author-email: ianb@colorstudy.com License: MIT Description: MiniMock ======== .. contents:: :depth: 1 -------------------- License & Repository -------------------- MiniMock is by `Ian Bicking `_ with substantial contributions by Mike Beachy, and is maintained by Josh Bronson. It is licensed under an `MIT-style license `_. It has a `bitbucket repository `_ which you can clone with ``hg clone https://jab@bitbucket.org/jab/minimock/``, download an archive of the tip from `http://bitbucket.org/jab/minimock/get/tip.gz `_, or install from with ``easy_install MiniMock==dev``. There is also a `Google Group `_ for the development mailing list which can be emailed at `minimock-dev@googlegroups.com `_. ------------ Introduction ------------ minimock is a simple library for doing Mock objects with doctest. When using doctest, mock objects can be very simple. Here's an example of something we might test, a simple email sender:: >>> import smtplib >>> def send_email(from_addr, to_addr, subject, body): ... conn = smtplib.SMTP('localhost') ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % ( ... to_addr, from_addr, subject, body) ... conn.sendmail(from_addr, [to_addr], msg) ... conn.quit() Now we want to make a mock ``smtplib.SMTP`` object. We'll have to inject our mock into the ``smtplib`` module:: >>> smtplib.SMTP = Mock('smtplib.SMTP') >>> smtplib.SMTP.mock_returns = Mock('smtp_connection') Now we do the test:: >>> send_email('ianb@colorstudy.com', 'joe@example.com', ... 'Hi there!', 'How is it going?') Called smtplib.SMTP('localhost') Called smtp_connection.sendmail( 'ianb@colorstudy.com', ['joe@example.com'], 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?') Called smtp_connection.quit() Voila! We've tested implicitly that no unexpected methods were called on the object. We've also tested the arguments that the mock object got. We've provided fake return calls (for the ``smtplib.SMTP()`` constructor). These are all the core parts of a mock library. The implementation is simple because most of the work is done by doctest. ----------------- Controlling Mocks ----------------- Mock objects have several attributes, all of which you can set when instantiating the object. To avoid name collision, all the attributes start with ``mock_``, while the constructor arguments don't. ``name``: The name of the object, used when printing out messages. In the example above it was ``'smtplib.SMTP'``. ``returns``: When this object is called, it will return this value. By default it is None. ``returns_iter``: Alternately, you can give an iterable of return results, like ``returns_iter=[1, 2, 3]``; on each subsequent call it will return the next value. ``returns_func``: If given, this will be called to get the return value. In essence, this function will be the *real* implementation of the method. ``raises``: An exception (instance or class) that will be raised when this object is called. ``tracker``: An object which is notified every time the mock object is called or an attribute is set on it (assuming ``show_attrs`` is ``True``); defaults to a ``Printer`` to stdout. ``TraceTracker`` can instead be useful for non-doctest tests. Pass ``None`` to disable this behavior. ``show_attrs``: If this is true, every time a new attribute is set on the mock object the tracker will be notified. Otherwise attribute sets are silent, and only calls trigger notification. So to create an object that always raises ValueError, do:: >>> dummy_module = Mock('mylibrary') >>> dummy_module.invalid_func.mock_raises = ValueError -------------- Creating Mocks -------------- Every attribute of a mock object will itself be another mock object, unless you specifically set it to something else. For instance, you can do:: >>> from minimock import Mock >>> dummy_module = Mock('mylibrary') >>> dummy_module.CONSTANT = 1 Then the ``CONSTANT`` value will persist. But you can also traverse to whatever object you want, and you will get another mock object. Another technique for creating a mock object is the ``mock(...)`` function. This works like:: >>> from minimock import mock >>> import os.path >>> mock('os.path.isfile', returns=True) This looks up the ``os.path.isfile`` object, and changes it to a mock object. Any keyword arguments you give (like ``returns=True`` in this example) will be used to create the mock object; you can also give a ``mock_obj`` keyword argument to pass in a mock object you've already created. This function looks in the calling function to figure out what to replace (``os.path.isfile`` in the example). You must import the proper modules first. Alternately you can pass in a dictionary like ``[locals(), globals()]`` for it to use for lookup. To restore all the objects mocked with ``mock()``, use ``minimock.restore()`` (with no arguments; all the mocks are kept track of). ---- News ---- 1.2.7 ----- * Fix for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.6 by the change to allow mocking static methods. Reported by Randy Syring. * bugfix: ``mock_show_attrs`` was immutable after initialization because the ``mock_`` prefix was accidentally left off in ``Mock.__setattr__`` (Yusuke Muraoka) 1.2.6 ----- * Allow changing the tracker on a mock object once it's been set (James Brady) * Support doctest use case (Israel Tsadok) * Fix issue 1: setting mock_returns_iter on existing Mock object (kenmacd) * Fix issue 2: static methods become unbound methods after mock + restore 1.2.5 ----- * Deprecate ``MockTracker``. ``TraceTracker`` should be used instead. 1.2.4 ----- * Fix show_attrs=True bug (Kendrick Shaw) 1.2.3 ----- * Explicitly passing ``tracker=None`` to the ``Mock`` constructor now suppresses tracking. If ``tracker`` is not passed it will still use ``Printer(sys.stdout)`` as before. 1.2.2 ----- * Added ``MinimockOutputChecker`` which normalizes whitespace in function call traces; ``TraceTracker`` now uses this instead of ``doctest.OutputChecker`` (Ben Finney) 1.2.1 ----- * Allow mocking of built-in functions. 1.2 --- * Added ``TraceTracker``, a better ``Tracker`` to use with unittests (James Brady) 1.1 --- * Added ``MockTracker`` for use with unittests rather than doctests (James Brady) 1.0 --- * Fixed setting special attributes like ``mock_returns`` on already-created Mock objects (Toby White) * Separated out printing to a class that accepts call information and provided an implementation that prints calls to a file. 0.9 --- * Added ``show_attrs`` 0.8 --- First official release. Keywords: mock testing unittest Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Software Development :: Testing MiniMock-1.2.7/setup.cfg000644 000765 000024 00000000151 11623500114 014735 0ustar00jabstaff000000 000000 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 [aliases] distribute = register sdist upload MiniMock-1.2.7/setup.py000644 000765 000024 00000001652 11623477660 014660 0ustar00jabstaff000000 000000 from setuptools import setup version = '1.2.7' try: from os.path import join, dirname doc_dir = join(dirname(__file__), 'docs') index = open(join(doc_dir, 'index.rst')).read() changelog = open(join(doc_dir, 'changelog.rst')).read() long_description = '\n'.join((index, changelog)) except IOError: long_description = 'Please see docs/index.rst for more info' setup( name='MiniMock', version=version, description='The simplest possible mock library', long_description=long_description, classifiers=[ 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: MIT License', 'Topic :: Software Development :: Testing', ], keywords='mock testing unittest', author='Ian Bicking', author_email='ianb@colorstudy.com', url='http://pypi.python.org/pypi/MiniMock', license='MIT', py_modules=['minimock'], zip_safe=True, ) MiniMock-1.2.7/MiniMock.egg-info/dependency_links.txt000644 000765 000024 00000000001 11623500114 022365 0ustar00jabstaff000000 000000 MiniMock-1.2.7/MiniMock.egg-info/PKG-INFO000644 000765 000024 00000022024 11623500114 017414 0ustar00jabstaff000000 000000 Metadata-Version: 1.0 Name: MiniMock Version: 1.2.7 Summary: The simplest possible mock library Home-page: http://pypi.python.org/pypi/MiniMock Author: Ian Bicking Author-email: ianb@colorstudy.com License: MIT Description: MiniMock ======== .. contents:: :depth: 1 -------------------- License & Repository -------------------- MiniMock is by `Ian Bicking `_ with substantial contributions by Mike Beachy, and is maintained by Josh Bronson. It is licensed under an `MIT-style license `_. It has a `bitbucket repository `_ which you can clone with ``hg clone https://jab@bitbucket.org/jab/minimock/``, download an archive of the tip from `http://bitbucket.org/jab/minimock/get/tip.gz `_, or install from with ``easy_install MiniMock==dev``. There is also a `Google Group `_ for the development mailing list which can be emailed at `minimock-dev@googlegroups.com `_. ------------ Introduction ------------ minimock is a simple library for doing Mock objects with doctest. When using doctest, mock objects can be very simple. Here's an example of something we might test, a simple email sender:: >>> import smtplib >>> def send_email(from_addr, to_addr, subject, body): ... conn = smtplib.SMTP('localhost') ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % ( ... to_addr, from_addr, subject, body) ... conn.sendmail(from_addr, [to_addr], msg) ... conn.quit() Now we want to make a mock ``smtplib.SMTP`` object. We'll have to inject our mock into the ``smtplib`` module:: >>> smtplib.SMTP = Mock('smtplib.SMTP') >>> smtplib.SMTP.mock_returns = Mock('smtp_connection') Now we do the test:: >>> send_email('ianb@colorstudy.com', 'joe@example.com', ... 'Hi there!', 'How is it going?') Called smtplib.SMTP('localhost') Called smtp_connection.sendmail( 'ianb@colorstudy.com', ['joe@example.com'], 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?') Called smtp_connection.quit() Voila! We've tested implicitly that no unexpected methods were called on the object. We've also tested the arguments that the mock object got. We've provided fake return calls (for the ``smtplib.SMTP()`` constructor). These are all the core parts of a mock library. The implementation is simple because most of the work is done by doctest. ----------------- Controlling Mocks ----------------- Mock objects have several attributes, all of which you can set when instantiating the object. To avoid name collision, all the attributes start with ``mock_``, while the constructor arguments don't. ``name``: The name of the object, used when printing out messages. In the example above it was ``'smtplib.SMTP'``. ``returns``: When this object is called, it will return this value. By default it is None. ``returns_iter``: Alternately, you can give an iterable of return results, like ``returns_iter=[1, 2, 3]``; on each subsequent call it will return the next value. ``returns_func``: If given, this will be called to get the return value. In essence, this function will be the *real* implementation of the method. ``raises``: An exception (instance or class) that will be raised when this object is called. ``tracker``: An object which is notified every time the mock object is called or an attribute is set on it (assuming ``show_attrs`` is ``True``); defaults to a ``Printer`` to stdout. ``TraceTracker`` can instead be useful for non-doctest tests. Pass ``None`` to disable this behavior. ``show_attrs``: If this is true, every time a new attribute is set on the mock object the tracker will be notified. Otherwise attribute sets are silent, and only calls trigger notification. So to create an object that always raises ValueError, do:: >>> dummy_module = Mock('mylibrary') >>> dummy_module.invalid_func.mock_raises = ValueError -------------- Creating Mocks -------------- Every attribute of a mock object will itself be another mock object, unless you specifically set it to something else. For instance, you can do:: >>> from minimock import Mock >>> dummy_module = Mock('mylibrary') >>> dummy_module.CONSTANT = 1 Then the ``CONSTANT`` value will persist. But you can also traverse to whatever object you want, and you will get another mock object. Another technique for creating a mock object is the ``mock(...)`` function. This works like:: >>> from minimock import mock >>> import os.path >>> mock('os.path.isfile', returns=True) This looks up the ``os.path.isfile`` object, and changes it to a mock object. Any keyword arguments you give (like ``returns=True`` in this example) will be used to create the mock object; you can also give a ``mock_obj`` keyword argument to pass in a mock object you've already created. This function looks in the calling function to figure out what to replace (``os.path.isfile`` in the example). You must import the proper modules first. Alternately you can pass in a dictionary like ``[locals(), globals()]`` for it to use for lookup. To restore all the objects mocked with ``mock()``, use ``minimock.restore()`` (with no arguments; all the mocks are kept track of). ---- News ---- 1.2.7 ----- * Fix for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.6 by the change to allow mocking static methods. Reported by Randy Syring. * bugfix: ``mock_show_attrs`` was immutable after initialization because the ``mock_`` prefix was accidentally left off in ``Mock.__setattr__`` (Yusuke Muraoka) 1.2.6 ----- * Allow changing the tracker on a mock object once it's been set (James Brady) * Support doctest use case (Israel Tsadok) * Fix issue 1: setting mock_returns_iter on existing Mock object (kenmacd) * Fix issue 2: static methods become unbound methods after mock + restore 1.2.5 ----- * Deprecate ``MockTracker``. ``TraceTracker`` should be used instead. 1.2.4 ----- * Fix show_attrs=True bug (Kendrick Shaw) 1.2.3 ----- * Explicitly passing ``tracker=None`` to the ``Mock`` constructor now suppresses tracking. If ``tracker`` is not passed it will still use ``Printer(sys.stdout)`` as before. 1.2.2 ----- * Added ``MinimockOutputChecker`` which normalizes whitespace in function call traces; ``TraceTracker`` now uses this instead of ``doctest.OutputChecker`` (Ben Finney) 1.2.1 ----- * Allow mocking of built-in functions. 1.2 --- * Added ``TraceTracker``, a better ``Tracker`` to use with unittests (James Brady) 1.1 --- * Added ``MockTracker`` for use with unittests rather than doctests (James Brady) 1.0 --- * Fixed setting special attributes like ``mock_returns`` on already-created Mock objects (Toby White) * Separated out printing to a class that accepts call information and provided an implementation that prints calls to a file. 0.9 --- * Added ``show_attrs`` 0.8 --- First official release. Keywords: mock testing unittest Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Software Development :: Testing MiniMock-1.2.7/MiniMock.egg-info/SOURCES.txt000644 000765 000024 00000000420 11623500114 020177 0ustar00jabstaff000000 000000 MANIFEST.in minimock.py setup.cfg setup.py MiniMock.egg-info/PKG-INFO MiniMock.egg-info/SOURCES.txt MiniMock.egg-info/dependency_links.txt MiniMock.egg-info/top_level.txt MiniMock.egg-info/zip-safe docs/.changelog.rst.un~ docs/changelog.rst docs/index.rst docs/license.txtMiniMock-1.2.7/MiniMock.egg-info/top_level.txt000644 000765 000024 00000000011 11623500114 021041 0ustar00jabstaff000000 000000 minimock MiniMock-1.2.7/MiniMock.egg-info/zip-safe000644 000765 000024 00000000001 11433037142 017754 0ustar00jabstaff000000 000000 MiniMock-1.2.7/docs/.changelog.rst.un~000644 000765 000024 00000111561 11623477635 017457 0ustar00jabstaff000000 000000 VimUnDo1K5_  VM_! ?5_VM_!A5_ VM_" B1.2.45_ VM_"g BA* Fix setting mock_returns_iter on existing Mock object (kenmacd)5_  VM_"l BI* Fix issue 1 setting mock_returns_iter on existing Mock object (kenmacd)5_ M` B5_ M` CJ* Fix issue 1: setting mock_returns_iter on existing Mock object (kenmacd)5_ M` CJ* Fix issue 2: setting mock_returns_iter on existing Mock object (kenmacd)5_ JM` CT* Fix issue 2: Static methods become unbound methods after mock + restore.(kenmacd)5_  M` CT* Fix issue 2: Static methods become unbound methods after mock + restore (kenmacd)5_  M` CS* Fix issue 2: Static methods become unbound methods after mock + restore (kenmacd)5_ IM` CS* Fix issue 2: static methods become unbound methods after mock + restore (kenmacd)5_M`:DC5_VM`B D5_VM`C F5_ VM`E 5_ VM`G F1.2.55_N%F*5_N%F * Fix bug where mock_show_attrs 5_ v N%F* bug where mock_show_attrs 5_ v N%F* bugfix: mock_show_attrs 5_ v N%F4* bugfix: mock_show_attrs was settable as show_attrs5_@ v N% F@* bugfix: mock_show_attrs was incorrectly settable as show_attrs5_  v N%%GK* bugfix: mock_show_attrs was incorrectly settable as show_attrs instead of5_ v N%)GM* bugfix: ``mock_show_attrs was incorrectly settable as show_attrs instead of5_L v N%/ GO* bugfix: ``mock_show_attrs`` was incorrectly settable as show_attrs instead of5_ v N%0 H of" mock_show_attrs (Yusuke Muraoka)5_ : v N%2GL* bugfix: ``mock_show_attrs`` was incorrectly settable as show_attrs instead5_! F v N%4GN* bugfix: ``mock_show_attrs`` was incorrectly settable as ``show_attrs instead5_ "!"",v,N%XGP* bugfix: ``mock_show_attrs`` was incorrectly settable as ``show_attrs`` instead5_!#"""-v-N%GH* bugfix: ``mock_show_attrs`` was not settable as ``show_attrs`` instead5_"$#,"-v-N%GE* bugfix: ``mock_show_attrs`` was immutable as ``show_attrs`` instead5_#%$,"-v-N%GL* bugfix: ``mock_show_attrs`` was immutable due to an ``show_attrs`` instead5_$&%"-v-N% G% of mock_show_attrs (Yusuke Muraoka)5_%'&"-v-N% G mock_5_&(' "-v-N% G ``mock_5_')(,"-v-N% G, ``mock_`` prefix was accidentally left off5_(*)"-v-N% HD ``mock_`` prefix was accidentally left off in ``Mock.__setattr__`` (Yusuke Muraoka)5_)+*L"-v-N% GU ``mock_`` prefix was accidentally left off in ``Mock.__setattr__`` (Yusuke Muraoka)5_*-+N%ȫIH5_+.,-N%I"* support mocking of proxy objects5_-/.N% I* support mocking proxy objects5_.0/8N%JJ* support mocking proxy objects (broken in fa70a05e4006 to support mocking5_/10@@AvAN% JR* support mocking proxy objects (broken in fa70a05e4006 / 1.2.6 to support mocking5_021@AvAN% K support mocking5_132E@AvAN%  KK* support mocking proxy objects (broken in fa70a05e4006 / 1.2.6 when static5_243 @AvAN%  L for mocking static method 5_354@AvAN%  K for mocking static method  static methods)5_465@AvAN% J+ for mocking static method static methods)5_576@@AvAN%JL* support mocking proxy objects (broken in fa70a05e4006 / 1.2.6 when support5_687@AvAN%(JF* support mocking proxy objects (broken in fa70a05e4006 / 1.2.6 which 5_798 @AvAN%*JJ* fix support mocking proxy objects (broken in fa70a05e4006 / 1.2.6 which 5_8:9'@AvAN%,JN* fix support for mocking proxy objects (broken in fa70a05e4006 / 1.2.6 which 5_9;:(@AvAN%?JO* fix support for mocking proxy objects. (broken in fa70a05e4006 / 1.2.6 which 5_:<;@AvAN%CJP* fix support for mocking proxy objects. (broken in fa70a05e4006 / 1.2.6 which 5_;=<)@AvAN%FJP* Fix support for mocking proxy objects. (broken in fa70a05e4006 / 1.2.6 which 5_<?=:@AvAN%IJ`* Fix support for mocking proxy objects. Worked in 1.2.5, (broken in fa70a05e4006 / 1.2.6 which 5_=@>?C@AvAN%T J_* Fix support for mocking proxy objects. Worked in 1.2.5, broken in fa70a05e4006 / 1.2.6 which 5_?A@A@AvAN%ZKC* Fix support for mocking proxy objects. Worked in 1.2.5, broken in5_@BAA@AvAN%cKC* Fix support for mocking proxy objects. Worked in 1.2.5, broken by5_ACBvN%g K fa70a05e4006 / 1.2.6 which 5_BDCvN%hKC* Fix support for mocking proxy objects. Worked in 1.2.5, broken in 1.2.6 which 5_CED8DRvN%kJP* Fix support for mocking proxy objects. Worked in 1.2.5, broken in 1.2.6 which 5_DFELDRvN%r JS* Fix support for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.6 which 5_EGFDRvN%s K which ' for mocking static methods was added)5_FHG v N%x J- which for mocking static methods was added)5_GIH/ v N%~ J: by the change to allow mocking static methods was added)5_HJI//=v=N%ɇ J? by the change to allow mocking static methods (fa70a05e4006).5_IKJ v N%ɓJL* Fix support for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.65_JLK1 v N%ɕJD* Fix for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.60 by the change to allow mocking static methods.5_KMLK v N%ə Is* Fix for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.6 by the change to allow mocking static methods.5_LNM) v N%ɣ J) change to allow mocking static methods.5_MONNN] KJ5_NOVNNhg tip------*5_=?>8@AvAN%OJb* Fix support for mocking proxy objects. Worked in 1.2.5 but broken in fa70a05e4006 / 1.2.6 which 5_+-, N%ȵI* support of proxy objects5_M_!?1.2.55MiniMock-1.2.7/docs/changelog.rst000644 000765 000024 00000003224 11623477635 016556 0ustar00jabstaff000000 000000 ---- News ---- 1.2.7 ----- * Fix for mocking proxy objects. Worked in 1.2.5 but broken in 1.2.6 by the change to allow mocking static methods. Reported by Randy Syring. * bugfix: ``mock_show_attrs`` was immutable after initialization because the ``mock_`` prefix was accidentally left off in ``Mock.__setattr__`` (Yusuke Muraoka) 1.2.6 ----- * Allow changing the tracker on a mock object once it's been set (James Brady) * Support doctest use case (Israel Tsadok) * Fix issue 1: setting mock_returns_iter on existing Mock object (kenmacd) * Fix issue 2: static methods become unbound methods after mock + restore 1.2.5 ----- * Deprecate ``MockTracker``. ``TraceTracker`` should be used instead. 1.2.4 ----- * Fix show_attrs=True bug (Kendrick Shaw) 1.2.3 ----- * Explicitly passing ``tracker=None`` to the ``Mock`` constructor now suppresses tracking. If ``tracker`` is not passed it will still use ``Printer(sys.stdout)`` as before. 1.2.2 ----- * Added ``MinimockOutputChecker`` which normalizes whitespace in function call traces; ``TraceTracker`` now uses this instead of ``doctest.OutputChecker`` (Ben Finney) 1.2.1 ----- * Allow mocking of built-in functions. 1.2 --- * Added ``TraceTracker``, a better ``Tracker`` to use with unittests (James Brady) 1.1 --- * Added ``MockTracker`` for use with unittests rather than doctests (James Brady) 1.0 --- * Fixed setting special attributes like ``mock_returns`` on already-created Mock objects (Toby White) * Separated out printing to a class that accepts call information and provided an implementation that prints calls to a file. 0.9 --- * Added ``show_attrs`` 0.8 --- First official release. MiniMock-1.2.7/docs/index.rst000644 000765 000024 00000012334 11304525011 015712 0ustar00jabstaff000000 000000 MiniMock ======== .. contents:: :depth: 1 -------------------- License & Repository -------------------- MiniMock is by `Ian Bicking `_ with substantial contributions by Mike Beachy, and is maintained by Josh Bronson. It is licensed under an `MIT-style license `_. It has a `bitbucket repository `_ which you can clone with ``hg clone https://jab@bitbucket.org/jab/minimock/``, download an archive of the tip from `http://bitbucket.org/jab/minimock/get/tip.gz `_, or install from with ``easy_install MiniMock==dev``. There is also a `Google Group `_ for the development mailing list which can be emailed at `minimock-dev@googlegroups.com `_. ------------ Introduction ------------ minimock is a simple library for doing Mock objects with doctest. When using doctest, mock objects can be very simple. Here's an example of something we might test, a simple email sender:: >>> import smtplib >>> def send_email(from_addr, to_addr, subject, body): ... conn = smtplib.SMTP('localhost') ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % ( ... to_addr, from_addr, subject, body) ... conn.sendmail(from_addr, [to_addr], msg) ... conn.quit() Now we want to make a mock ``smtplib.SMTP`` object. We'll have to inject our mock into the ``smtplib`` module:: >>> smtplib.SMTP = Mock('smtplib.SMTP') >>> smtplib.SMTP.mock_returns = Mock('smtp_connection') Now we do the test:: >>> send_email('ianb@colorstudy.com', 'joe@example.com', ... 'Hi there!', 'How is it going?') Called smtplib.SMTP('localhost') Called smtp_connection.sendmail( 'ianb@colorstudy.com', ['joe@example.com'], 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?') Called smtp_connection.quit() Voila! We've tested implicitly that no unexpected methods were called on the object. We've also tested the arguments that the mock object got. We've provided fake return calls (for the ``smtplib.SMTP()`` constructor). These are all the core parts of a mock library. The implementation is simple because most of the work is done by doctest. ----------------- Controlling Mocks ----------------- Mock objects have several attributes, all of which you can set when instantiating the object. To avoid name collision, all the attributes start with ``mock_``, while the constructor arguments don't. ``name``: The name of the object, used when printing out messages. In the example above it was ``'smtplib.SMTP'``. ``returns``: When this object is called, it will return this value. By default it is None. ``returns_iter``: Alternately, you can give an iterable of return results, like ``returns_iter=[1, 2, 3]``; on each subsequent call it will return the next value. ``returns_func``: If given, this will be called to get the return value. In essence, this function will be the *real* implementation of the method. ``raises``: An exception (instance or class) that will be raised when this object is called. ``tracker``: An object which is notified every time the mock object is called or an attribute is set on it (assuming ``show_attrs`` is ``True``); defaults to a ``Printer`` to stdout. ``TraceTracker`` can instead be useful for non-doctest tests. Pass ``None`` to disable this behavior. ``show_attrs``: If this is true, every time a new attribute is set on the mock object the tracker will be notified. Otherwise attribute sets are silent, and only calls trigger notification. So to create an object that always raises ValueError, do:: >>> dummy_module = Mock('mylibrary') >>> dummy_module.invalid_func.mock_raises = ValueError -------------- Creating Mocks -------------- Every attribute of a mock object will itself be another mock object, unless you specifically set it to something else. For instance, you can do:: >>> from minimock import Mock >>> dummy_module = Mock('mylibrary') >>> dummy_module.CONSTANT = 1 Then the ``CONSTANT`` value will persist. But you can also traverse to whatever object you want, and you will get another mock object. Another technique for creating a mock object is the ``mock(...)`` function. This works like:: >>> from minimock import mock >>> import os.path >>> mock('os.path.isfile', returns=True) This looks up the ``os.path.isfile`` object, and changes it to a mock object. Any keyword arguments you give (like ``returns=True`` in this example) will be used to create the mock object; you can also give a ``mock_obj`` keyword argument to pass in a mock object you've already created. This function looks in the calling function to figure out what to replace (``os.path.isfile`` in the example). You must import the proper modules first. Alternately you can pass in a dictionary like ``[locals(), globals()]`` for it to use for lookup. To restore all the objects mocked with ``mock()``, use ``minimock.restore()`` (with no arguments; all the mocks are kept track of). MiniMock-1.2.7/docs/license.txt000644 000765 000024 00000002060 11256764727 016260 0ustar00jabstaff000000 000000 Copyright (c) 2007 Ian Bicking and Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.