blob: 7bdc536faf5eeae726332156f965c47596d14c4b [file] [log] [blame]
Michael Foord1e68bec2012-03-03 22:24:30 +00001# Copyright (C) 2007-2012 Michael Foord & the mock team
2# E-mail: fuzzyman AT voidspace DOT org DOT uk
3# http://www.voidspace.org.uk/python/mock/
4
5import inspect
6
7from tests.support import unittest2
8
9from mock import Mock, mocksignature, patch
10
11
12class Something(object):
13 def __init__(self, foo, bar=10):
14 pass
15 def __call__(self, foo, bar=5):
16 pass
17
18something = Something(1, 2)
19
20
21def f(a, b, c):
22 pass
23
24
25class TestMockSignature(unittest2.TestCase):
26
27 def test_function(self):
28 def f(a):
29 pass
30 mock = Mock()
31
32 f2 = mocksignature(f, mock)
33 self.assertIs(f2.mock, mock)
34
35 self.assertRaises(TypeError, f2)
36 mock.return_value = 3
37 self.assertEqual(f2('foo'), 3)
38 mock.assert_called_with('foo')
39 f2.mock.assert_called_with('foo')
40
41
42 def test_function_without_explicit_mock(self):
43 def f(a):
44 pass
45
46 f2 = mocksignature(f)
47 self.assertIsInstance(f2.mock, Mock)
48
49 self.assertRaises(TypeError, f2)
50 f2.mock.return_value = 3
51 self.assertEqual(f2('foo'), 3)
52 f2.mock.assert_called_with('foo')
53
54
55 def test_method(self):
56 class Foo(object):
57 def method(self, a, b):
58 pass
59
60 f = Foo()
61 mock = Mock()
62 mock.return_value = 3
63 f.method = mocksignature(f.method, mock)
64 self.assertEqual(f.method('foo', 'bar'), 3)
65 mock.assert_called_with('foo', 'bar')
66
67
68 def test_function_with_defaults(self):
69 def f(a, b=None):
70 pass
71 mock = Mock()
72 f2 = mocksignature(f, mock)
73 f2(3)
74 mock.assert_called_with(3, None)
75 mock.reset_mock()
76
77 f2(1, 7)
78 mock.assert_called_with(1, 7)
79 mock.reset_mock()
80
81 f2(b=1, a=7)
82 mock.assert_called_with(7, 1)
83 mock.reset_mock()
84
85 a = object()
86 def f(a=a):
87 pass
88 f2 = mocksignature(f, mock)
89 f2()
90 mock.assert_called_with(a)
91
92
93 def test_introspection(self):
94 def f(a, *args, **kwargs):
95 pass
96 f2 = mocksignature(f, f)
97 self.assertEqual(inspect.getargspec(f), inspect.getargspec(f2))
98
99 def f(a, b=None, c=3, d=object()):
100 pass
101 f2 = mocksignature(f, f)
102 self.assertEqual(inspect.getargspec(f), inspect.getargspec(f2))
103
104
105 def test_function_with_varargs_and_kwargs(self):
106 def f(a, b=None, *args, **kwargs):
107 return (a, b, args, kwargs)
108 f2 = mocksignature(f, f)
109 self.assertEqual(f2(3, 4, 5, x=6, y=9), (3, 4, (5,), {'x': 6, 'y': 9}))
110 self.assertEqual(f2(3, x=6, y=9, b='a'), (3, 'a', (), {'x': 6, 'y': 9}))
111
112 def f(*args):
113 pass
114 g = mocksignature(f)
115 g.mock.return_value = 3
116 self.assertEqual(g(1, 2, 'many'), 3)
117 self.assertEqual(g(), 3)
118 self.assertRaises(TypeError, lambda: g(a=None))
119
120 def f(**kwargs):
121 pass
122 g = mocksignature(f)
123 g.mock.return_value = 3
124 self.assertEqual(g(), 3)
125 self.assertEqual(g(a=None, b=None), 3)
126 self.assertRaises(TypeError, lambda: g(None))
127
128
129 def test_mocksignature_with_patch(self):
130 mock = Mock()
131
132 def f(a, b, c):
133 pass
134 mock.f = f
135
136 @patch.object(mock, 'f', mocksignature=True)
137 def test(mock_f):
138 self.assertRaises(TypeError, mock.f, 3, 4)
139 self.assertRaises(TypeError, mock.f, 3, 4, 5, 6)
140 mock.f(1, 2, 3)
141
142 mock_f.assert_called_with(1, 2, 3)
143 mock.f.mock.assert_called_with(1, 2, 3)
144
145 test()
146
147 @patch('tests.support.SomeClass.wibble', mocksignature=True)
148 def test(mock_wibble):
149 from tests.support import SomeClass
150
151 instance = SomeClass()
152 self.assertRaises(TypeError, instance.wibble, 1)
153 instance.wibble()
154
155 mock_wibble.assert_called_with(instance)
156 instance.wibble.mock.assert_called_with(instance)
157
158 test()
159
160
161 @unittest2.skipUnless(__debug__, 'assert disabled when run with -O/OO')
162 def test_mocksignature_with_reserved_arg(self):
163 def f(_mock_):
164 pass
165 self.assertRaises(AssertionError, lambda: mocksignature(f))
166
167 def f(_mock_=None):
168 pass
169 self.assertRaises(AssertionError, lambda: mocksignature(f))
170
171 def f(*_mock_):
172 pass
173 self.assertRaises(AssertionError, lambda: mocksignature(f))
174
175 def f(**_mock_):
176 pass
177 self.assertRaises(AssertionError, lambda: mocksignature(f))
178
179
180 def test_mocksignature_class(self):
181 MockedSomething = mocksignature(Something)
182
183 result = MockedSomething(5, 23)
184 self.assertIs(result, MockedSomething.mock.return_value)
185
186 MockedSomething(1)
187 MockedSomething.mock.assert_caled_with(1, 10)
188
189 self.assertRaises(TypeError, MockedSomething)
190
191
192 def test_mocksignature_callable(self):
193 mocked_something = mocksignature(something)
194
195 result = mocked_something(5, 23)
196 self.assertIs(result, mocked_something.mock.return_value)
197
198 mocked_something(1)
199 mocked_something.mock.assert_caled_with(1, 5)
200
201 self.assertRaises(TypeError, mocked_something)
202
203
204 def test_patch_mocksignature_class(self):
205 original_something = Something
206 something_name = '%s.Something' % __name__
207 @patch(something_name, mocksignature=True)
208 def test(MockSomething):
209 Something(3, 5)
210 MockSomething.assert_called_with(3, 5)
211
212 Something(6)
213 MockSomething.assert_called_with(6, 10)
214
215 self.assertRaises(TypeError, Something)
216 test()
217 self.assertIs(Something, original_something)
218
219
220 def test_patch_mocksignature_callable(self):
221 original_something = something
222 something_name = '%s.something' % __name__
223 @patch(something_name, mocksignature=True)
224 def test(MockSomething):
225 something(3, 4)
226 MockSomething.assert_called_with(3, 4)
227
228 something(6)
229 MockSomething.assert_called_with(6, 5)
230
231 self.assertRaises(TypeError, something)
232 test()
233 self.assertIs(something, original_something)
234
235
236 def test_patchobject_mocksignature(self):
237 class something(object):
238 def meth(self, a, b, c):
239 pass
240
241 original = something.__dict__['meth']
242
243 @patch.object(something, 'meth', mocksignature=True)
244 def test(_):
245 self.assertIsNot(something.__dict__['meth'], original)
246 thing = something()
247 thing.meth(1, 2, 3)
248 self.assertRaises(TypeError, thing.meth, 1)
249
250 test()
251 self.assertIs(something.__dict__['meth'], original)
252
253 thing = something()
254
255 original = thing.meth
256 @patch.object(thing, 'meth', mocksignature=True)
257 def test(_):
258 thing.meth(1, 2, 3)
259 self.assertRaises(TypeError, thing.meth, 1)
260
261 test()
262 self.assertEqual(thing.meth, original)
263
264 # when patching instance methods using mocksignatures we used to
265 # replace the bound method with an instance attribute on unpatching.
266 self.assertNotIn('meth', thing.__dict__)
267
268
269 def test_assert_called_with(self):
270 func = mocksignature(f)
271
272 self.assertRaises(AssertionError, func.assert_called_with)
273 self.assertRaises(AssertionError, func.assert_called_once_with)
274
275 func(1, 2, 3)
276 func.assert_called_with(1, 2, 3)
277 self.assertRaises(AssertionError, func.assert_called_with, 4, 5, 6)
278 func.assert_called_once_with(1, 2, 3)
279 self.assertRaises(AssertionError, func.assert_called_once_with,
280 4, 5, 6)
281
282
283 def test_mock_attributes(self):
284 func = mocksignature(f)
285
286 return_value = func.return_value
287 self.assertIsInstance(return_value, Mock)
288 self.assertIsNone(func.side_effect)
289 self.assertFalse(func.called)
290 self.assertIsNone(func.call_args)
291 self.assertEqual(func.call_count, 0)
292 self.assertEqual(func.method_calls, [])
293 self.assertEqual(func.call_args_list, [])
294 self.assertIs(func._mock_children, func.mock._mock_children)
295
296 self.assertIs(func(1, 2, 3), return_value)
297
298 self.assertTrue(func.called)
299 self.assertEqual(func.call_args, ((1, 2, 3), {}))
300 self.assertEqual(func.call_count, 1)
301 self.assertEqual(func.method_calls, [])
302 self.assertEqual(func.call_args_list, [((1, 2, 3), {})])
303 func.method_calls.append('foo')
304
305 return_value()
306 func.reset_mock()
307
308 self.assertEqual(return_value.call_count, False)
309 self.assertFalse(func.called)
310 self.assertIsNone(func.call_args)
311 self.assertEqual(func.call_count, 0)
312 self.assertEqual(func.method_calls, [])
313 self.assertEqual(func.call_args_list, [])
314 self.assertIs(func._mock_children, func.mock._mock_children)
315
316 func.side_effect = KeyError
317 self.assertRaises(KeyError, func, 1, 2, 3)
318 self.assertTrue(func.called)
319
320 func.side_effect = None
321 func.return_value = 'foo'
322 self.assertEqual(func(1, 2, 3), 'foo')
323 self.assertEqual(func.call_count, 2)
324
325
326 def test_return_value_from_existing_mock(self):
327 mock = Mock(return_value='foo')
328 func = mocksignature(f, mock)
329 self.assertEqual(func(1, 2, 3), 'foo')
330
331 mock.return_value = 'bar'
332 self.assertEqual(func(1, 2, 3), 'bar')
333
334
335 def test_side_effect_from_existing_mock(self):
336 mock = Mock(side_effect=KeyError)
337 func = mocksignature(f, mock)
338 self.assertRaises(KeyError, func, 1, 2, 3)
339
340 mock.side_effect = NameError
341 self.assertRaises(NameError, func, 1, 2, 3)
342
343
344if __name__ == '__main__':
345 unittest2.main()