Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added the ability to return multiple values (for sequential calls) by…

… providing more than one argument to `then_return(...)`
  • Loading branch information...
commit fbdeb00eeda6b50faf8b57af436265afa1ba5852 1 parent 4618482
@gfxmonk authored
View
4 Makefile
@@ -39,6 +39,10 @@ clean:
test: mocktest-local.xml
0launch --command=test mocktest-local.xml
+test-all: mocktest-local.xml
+ 0install run http://0install.net/2008/interfaces/0test.xml mocktest-local.xml \
+ http://repo.roscidus.com/python/python 2.6,2.7 2.7,2.8 3.0,4
+
mocktest-local.xml: mocktest.xml
0local mocktest.xml
View
2  VERSION
@@ -1 +1 @@
-0.6.4
+0.6.5
View
4 conf.py
@@ -45,9 +45,9 @@
# built documents.
#
# The short X.Y version.
-version = '0.6.4'
+version = '0.6.5'
# The full version, including alpha/beta/rc tags.
-release = '0.6.4'
+release = '0.6.5'
autodoc_default_flags = ['members']
View
7 mocktest.xml
@@ -56,7 +56,8 @@ http://gfxmonk.net/dist/doc/mocktest/doc/
<group>
<environment insert="" mode="prepend" name="PYTHONPATH"/>
<command name="test">
- <runner command="run-py2" interface="http://gfxmonk.net/dist/0install/nosetests-runner.xml"/>
+ <runner command="core" interface="http://gfxmonk.net/dist/0install/nosetests-runner.xml"/>
+ <requires importance="optional" interface="http://gfxmonk.net/dist/0install/rednose.xml"/>
</command>
<requires interface="http://repo.roscidus.com/python/python">
<version before="3"/>
@@ -89,5 +90,9 @@ http://gfxmonk.net/dist/doc/mocktest/doc/
<manifest-digest sha256="9611e5c4bda7db3c0ebcde226e1756b5378987c3e08742bf720d62cb2ce4a502"/>
<archive href="http://gfxmonk.net/dist/0install/mocktest/mocktest-0.6.4.tgz" size="49933"/>
</implementation>
+ <implementation id="sha1new=675de1efa34f9f0c87a66f5c3d41b3ed5caafcdd" released="2013-01-25" version="0.6.5">
+ <manifest-digest sha256="13bd6e5e44cd0925b241f683bd91d574366290edf9aeb0d9687b40c9044abaaa"/>
+ <archive href="http://gfxmonk.net/dist/0install/mocktest/mocktest-0.6.5.tgz" size="51074"/>
+ </implementation>
</group>
</interface>
View
43 mocktest/mocking.py
@@ -17,6 +17,7 @@
'Object',
]
+class ReturnValuesExhausted(Exception): pass
Settable = collections.namedtuple('Settable', ('get','set','delete', 'error'))
Item = Settable(
@@ -379,10 +380,22 @@ def __call__(self, *a, **kw):
self.received_calls.append(call)
for act in reversed(self._acts):
if act._matches(call):
- return act._act_upon(call)
+ try:
+ return act._act_upon(call)
+ except ReturnValuesExhausted:
+ raise AssertionError(
+ "%r ran out of return values.\n"
+ "Received %s"
+ % (act, act.describe_reality(self.received_calls)))
else:
act_condition_descriptions = [" - " + act.condition_description for act in reversed(self._acts)]
- raise TypeError("stubbed method %r received unexpected arguments: %s\nAllowable argument conditions are:\n%s" % (self._name, call.desc(),"\n".join(act_condition_descriptions)))
+ raise TypeError(
+ "stubbed method %r received unexpected arguments: %s\n"
+ "Allowable argument conditions are:\n%s" % (
+ self._name,
+ call.desc(),
+ "\n".join(act_condition_descriptions))
+ )
def _verify(self):
for act in self._acts:
@@ -612,9 +625,21 @@ def describe_reality(self, call_list):
i += 1
return desc
- def and_return(self, val):
+ def and_return(self, val, *subsequent_vals):
"""
When this act matches, return the given `result` to the caller.
+ If provided with multiple arguments, those values will be returned in order. e.g:
+
+ >>> expect(obj).foo().and_return(True, True, False)
+ >>> obj.foo()
+ True
+ >>> obj.foo()
+ True
+ >>> obj.foo()
+ False
+
+ Once all return values have been used up, any further calls with throw a :class:`~mocktest.MockError`.
+
**Note:** :func:`and_raise`, :func:`and_return` and :func:`and_call` each have a `then_*` alias
for better readability when using :func:`when`. e.g:
@@ -627,7 +652,17 @@ def and_return(self, val):
Both `and_` and `then_` versions have the same effect however.
"""
- self._action = lambda *a, **k: val
+ if subsequent_vals:
+ vals = [val] + list(subsequent_vals)
+ def action(*a, **k):
+ try:
+ return vals.pop(0)
+ except IndexError:
+ raise ReturnValuesExhausted()
+
+ self._action = action
+ else:
+ self._action = lambda *a, **k: val
return self
then_return = and_return
View
8 setup.py
@@ -7,12 +7,12 @@
from setuptools import *
setup(
packages = find_packages(exclude=['test', 'test.*']),
- description='mocking library for python, inspired by rspec',
- url='http://gfxmonk.net/dist/0install/mocktest.xml',
+ name='mocktest',
install_requires=['setuptools'],
- version='0.6.4',
long_description="\n**Note**: This package has been built automatically by\n`zero2pypi <http://gfxmonk.net/dist/0install/zero2pypi.xml>`_.\nIf possible, you should use the zero-install feed instead:\nhttp://gfxmonk.net/dist/0install/mocktest.xml\n\n----------------\n\nmocktest\n********\n... is a powerful and easy-to-use mocking library, inspired by rspec and\nsimilar in some ways to Michael Foord's popular Mock module.\n\nSource / Issues:\nhttp://github.com/gfxmonk/mocktest/tree/master\n\n\nZero install feed:\nhttp://gfxmonk.net/dist/0install/mocktest.xml\n(this is the preferred distribution method)\n\n\nCheese shop entry:\nhttp://pypi.python.org/pypi/mocktest\n\n\nDocumentation / Installation\n----------------------------\nPlease see the full documentation online at:\nhttp://gfxmonk.net/dist/doc/mocktest/doc/\n",
- name='mocktest',
+ description='mocking library for python, inspired by rspec',
+ url='http://gfxmonk.net/dist/0install/mocktest.xml',
+ version='0.6.5',
classifiers=[
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
View
13 test/mocking_test.py
@@ -49,6 +49,19 @@ def test_return_values(self):
assert obj.meth(1,2,3) == '123'
assert obj.meth(3, 2, 1) == 'foo'
self.assertRaises(AttributeError, lambda: obj.meth2)
+
+ @passing
+ def test_multiple_return_values(self):
+ when(obj).meth.then_return('foo', 'bar', 'baz')
+ assert obj.meth() == 'foo'
+ assert obj.meth() == 'bar'
+ assert obj.meth() == 'baz'
+ try:
+ obj.meth()
+ self.fail()
+ except AssertionError, e:
+ self.assertTrue("Stubbed method 'meth' ran out of return values." in str(e))
+ self.assertTrue("Received 4 calls with arguments:\n" in str(e))
def test_should_revert_all_replaced_attrs(self):
self.assertEquals(_dir(obj), [])
Please sign in to comment.
Something went wrong with that request. Please try again.