summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Niemeyer <gustavo@niemeyer.net>2010-07-29 20:51:24 -0400
committerGustavo Niemeyer <gustavo@niemeyer.net>2010-07-29 20:51:24 -0400
commitc073b8161478bd8068dbdc9780733104a5346bcb (patch)
tree92f6ce457038fb64f8644d037fb7c3c50dc0ceee
parent3a1d9b8548f074c44c853e0ccaeb40edf83a7b0b (diff)
downloadmocker-c073b8161478bd8068dbdc9780733104a5346bcb.tar.gz
mocker.call() now supports a with_object argument. If True, the called
function will receive the patched or proxied object so that its state may be used or verified in checks.
-rw-r--r--NEWS8
-rw-r--r--mocker.py15
-rwxr-xr-xtest.py62
3 files changed, 81 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index b904592..c508df5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+1.1 (2010-XX-XX)
+================
+
+- mocker.call() now supports a with_object argument. If True, the called
+ function will receive the patched or proxied object so that its state
+ may be used or verified in checks.
+
+
1.0 (2010-06-20)
=================
diff --git a/mocker.py b/mocker.py
index 2d7f59b..a453ab5 100644
--- a/mocker.py
+++ b/mocker.py
@@ -847,14 +847,17 @@ class MockerBase(object):
raise exception
self.call(raise_exception)
- def call(self, func):
+ def call(self, func, with_object=False):
"""Make the last recorded event cause the given function to be called.
@param func: Function to be called.
The result of the function will be used as the event result.
"""
- self._events[-1].add_task(FunctionRunner(func))
+ event = self._events[-1]
+ if with_object and event.path.root_object is None:
+ raise TypeError("Mock object isn't a proxy")
+ event.add_task(FunctionRunner(func, with_root_object=with_object))
def count(self, min, max=False):
"""Last recorded event must be replayed between min and max times.
@@ -1845,12 +1848,16 @@ class FunctionRunner(Task):
and the function result is also returned.
"""
- def __init__(self, func):
+ def __init__(self, func, with_root_object=False):
self._func = func
+ self._with_root_object = with_root_object
def run(self, path):
action = path.actions[-1]
- return self._func(*action.args, **action.kwargs)
+ if self._with_root_object:
+ return self._func(path.root_object, *action.args, **action.kwargs)
+ else:
+ return self._func(*action.args, **action.kwargs)
class PathExecuter(Task):
diff --git a/test.py b/test.py
index 827cbea..9c3e401 100755
--- a/test.py
+++ b/test.py
@@ -150,6 +150,26 @@ class IntegrationTest(TestCase):
self.assertEquals(obj.x(24), 42)
self.assertEquals(calls, [24])
+ def test_call_with_object(self):
+ class C(object):
+ def method(self, a, b, c):
+ return "Running real method?"
+
+ calls = []
+ def func(*args, **kwargs):
+ calls.append(args)
+ calls.append(kwargs)
+ return 4
+
+ mock = self.mocker.patch(C)
+ mock.method(1, 2, c=3)
+ self.mocker.call(func, with_object=True)
+ self.mocker.replay()
+
+ obj = C()
+ self.assertEquals(obj.method(1, 2, c=3), 4) # Mocked.
+ self.assertEquals(calls, [(obj, 1, 2), {"c": 3}])
+
def test_generate(self):
obj = self.mocker.mock()
obj.x(24)
@@ -1598,6 +1618,41 @@ class MockerTest(TestCase):
self.mocker.call(lambda *args, **kwargs: 123)
self.assertEquals(event2.run(self.path), 123)
+ def test_call_with_object(self):
+ obj = object()
+ mock = self.mocker.proxy(obj)
+ action = Action("getattr", ("attr",), {}, Path(mock, root_object=456))
+ path = action.path + self.action
+ event1 = self.mocker.add_event(Event(path))
+ event2 = self.mocker.add_event(Event(path))
+ self.mocker.call(lambda *args, **kwargs: (args, kwargs),
+ with_object=True)
+ self.assertEquals(event1.get_tasks(), [])
+ (task,) = event2.get_tasks()
+ self.assertEquals(type(task), FunctionRunner)
+ self.assertEquals(event2.run(event2.path), ((456, "attr"), {}))
+
+ def test_call_with_object_needs_proxy(self):
+ obj = object()
+ mock = self.mocker.proxy(obj)
+ action = Action("getattr", ("attr",), {}, Path(mock, root_object=456))
+ path = action.path + self.action
+ event1 = self.mocker.add_event(Event(path))
+ event2 = self.mocker.add_event(Event(path))
+ self.mocker.call(lambda *args, **kwargs: (args, kwargs),
+ with_object=True)
+ self.assertEquals(event1.get_tasks(), [])
+ (task,) = event2.get_tasks()
+ self.assertEquals(type(task), FunctionRunner)
+ self.assertEquals(event2.run(event2.path), ((456, "attr"), {}))
+
+ def test_call_with_object_fails_on_unproxied(self):
+ mock = self.mocker.mock()
+ event1 = self.mocker.add_event(Event(Path(mock)))
+ event2 = self.mocker.add_event(Event(Path(mock)))
+ self.assertRaises(TypeError, self.mocker.call,
+ lambda *args: None, with_object=True)
+
def test_count(self):
event1 = self.mocker.add_event(Event())
event2 = self.mocker.add_event(Event())
@@ -3328,6 +3383,13 @@ class FunctionRunnerTest(TestCase):
result = task.run(self.path)
self.assertEquals(result, "((1, 2), {'c': 3})")
+ def test_run_with_object(self):
+ task = FunctionRunner(lambda *args, **kwargs: repr((args, kwargs)),
+ with_root_object=True)
+ self.path.root_object = 4
+ result = task.run(self.path)
+ self.assertEquals(result, "((4, 1, 2), {'c': 3})")
+
class PathExecuterTest(TestCase):