Skip to content
This repository was archived by the owner on Sep 12, 2021. It is now read-only.

Commit 4adbc11

Browse files
committed
support chaining
1 parent a8e6d3e commit 4adbc11

3 files changed

Lines changed: 33 additions & 7 deletions

File tree

mockito/invocation.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# coding: utf-8
33

44
import matchers
5+
from verification import Times
6+
57

68
__copyright__ = "Copyright 2008-2010, Mockito Contributors"
79
__license__ = "MIT"
@@ -21,7 +23,9 @@ def __init__(self, mock, method_name):
2123
self.named_params = {}
2224
self.answers = []
2325
self.strict = mock.strict
24-
26+
from mockito import mock
27+
self.chain = mock(chainable=True)
28+
2529
def _remember_params(self, params, named_params):
2630
self.params = params
2731
self.named_params = named_params
@@ -64,13 +68,13 @@ class RememberedInvocation(Invocation):
6468
def __call__(self, *params, **named_params):
6569
self._remember_params(params, named_params)
6670
self.mock.remember(self)
67-
71+
6872
for matching_invocation in self.mock.stubbed_invocations:
6973
if matching_invocation.matches(self):
7074
return matching_invocation.answer_first()
7175

72-
return None
73-
76+
return self.chain if self.mock.chainable else None
77+
7478
class RememberedProxyInvocation(Invocation):
7579
'''Remeber params and proxy to method of original object.
7680
@@ -99,13 +103,17 @@ def __call__(self, *params, **named_params):
99103

100104
for invocation in matched_invocations:
101105
invocation.verified = True
106+
if self.mock.chainable:
107+
invocation.chain.verification = Times(1)
108+
return invocation.chain
109+
102110

103111
class StubbedInvocation(MatchingInvocation):
104112
def __init__(self, *params):
105113
super(StubbedInvocation, self).__init__(*params)
106114
if self.mock.strict:
107115
self.ensure_mocked_object_has_method(self.method_name)
108-
116+
109117
def ensure_mocked_object_has_method(self, method_name):
110118
if not self.mock.has_method(method_name):
111119
raise InvocationError("You tried to stub a method '%s' the object (%s) doesn't have."
@@ -120,7 +128,7 @@ def stub_with(self, answer):
120128
self.answers.append(answer)
121129
self.mock.stub(self.method_name)
122130
self.mock.finish_stubbing(self)
123-
131+
124132
class AnswerSelector(object):
125133
def __init__(self, invocation):
126134
self.invocation = invocation
@@ -136,6 +144,12 @@ def thenRaise(self, *exceptions):
136144
self.__then(Raise(exception))
137145
return self
138146

147+
def __getattr__(self, name):
148+
return_value = self.invocation.chain
149+
self.__then(Return(return_value))
150+
return_value.expect_stubbing()
151+
return getattr(return_value, name)
152+
139153
def __then(self, answer):
140154
if not self.answer:
141155
self.answer = CompositeAnswer(answer)

mockito/mocking.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def fromMethod(meth):
7979
import inspect
8080

8181
class mock(TestDouble):
82-
def __init__(self, mocked_obj=None, strict=True):
82+
def __init__(self, mocked_obj=None, strict=True, chainable=False):
8383
self.invocations = []
8484
self.stubbed_invocations = []
8585
self.original_methods = []
@@ -95,6 +95,7 @@ def __init__(self, mocked_obj=None, strict=True):
9595
self.zi = isinstance(mocked_obj, zi.interface.InterfaceClass)
9696
else:
9797
self.zi = False
98+
self.chainable = chainable
9899

99100
mock_registry.register(self)
100101

mockito_test/stubbing_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ def bar_name(a):
268268
else:
269269
self.assertTrue(False, "StubbingError not raised")
270270

271+
def testChainableStubs(self):
272+
person = mock(chainable=True)
273+
person.needs().help(10)
274+
verify(person).needs().help(10)
275+
276+
that = mock(chainable=True)
277+
when(that).a().b(10).thenReturn(20)
278+
x = that.a().b(10)
279+
self.assertEquals(x, 20)
280+
281+
271282
# TODO: verify after stubbing and vice versa
272283

273284
if __name__ == '__main__':

0 commit comments

Comments
 (0)