python/mock-1.0.0/tests/testmagicmethods.py

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 # Copyright (C) 2007-2012 Michael Foord & the mock team
michael@0 2 # E-mail: fuzzyman AT voidspace DOT org DOT uk
michael@0 3 # http://www.voidspace.org.uk/python/mock/
michael@0 4
michael@0 5 from tests.support import unittest2, inPy3k
michael@0 6
michael@0 7 try:
michael@0 8 unicode
michael@0 9 except NameError:
michael@0 10 # Python 3
michael@0 11 unicode = str
michael@0 12 long = int
michael@0 13
michael@0 14 import inspect
michael@0 15 import sys
michael@0 16 from mock import Mock, MagicMock, _magics
michael@0 17
michael@0 18
michael@0 19
michael@0 20 class TestMockingMagicMethods(unittest2.TestCase):
michael@0 21
michael@0 22 def test_deleting_magic_methods(self):
michael@0 23 mock = Mock()
michael@0 24 self.assertFalse(hasattr(mock, '__getitem__'))
michael@0 25
michael@0 26 mock.__getitem__ = Mock()
michael@0 27 self.assertTrue(hasattr(mock, '__getitem__'))
michael@0 28
michael@0 29 del mock.__getitem__
michael@0 30 self.assertFalse(hasattr(mock, '__getitem__'))
michael@0 31
michael@0 32
michael@0 33 def test_magicmock_del(self):
michael@0 34 mock = MagicMock()
michael@0 35 # before using getitem
michael@0 36 del mock.__getitem__
michael@0 37 self.assertRaises(TypeError, lambda: mock['foo'])
michael@0 38
michael@0 39 mock = MagicMock()
michael@0 40 # this time use it first
michael@0 41 mock['foo']
michael@0 42 del mock.__getitem__
michael@0 43 self.assertRaises(TypeError, lambda: mock['foo'])
michael@0 44
michael@0 45
michael@0 46 def test_magic_method_wrapping(self):
michael@0 47 mock = Mock()
michael@0 48 def f(self, name):
michael@0 49 return self, 'fish'
michael@0 50
michael@0 51 mock.__getitem__ = f
michael@0 52 self.assertFalse(mock.__getitem__ is f)
michael@0 53 self.assertEqual(mock['foo'], (mock, 'fish'))
michael@0 54 self.assertEqual(mock.__getitem__('foo'), (mock, 'fish'))
michael@0 55
michael@0 56 mock.__getitem__ = mock
michael@0 57 self.assertTrue(mock.__getitem__ is mock)
michael@0 58
michael@0 59
michael@0 60 def test_magic_methods_isolated_between_mocks(self):
michael@0 61 mock1 = Mock()
michael@0 62 mock2 = Mock()
michael@0 63
michael@0 64 mock1.__iter__ = Mock(return_value=iter([]))
michael@0 65 self.assertEqual(list(mock1), [])
michael@0 66 self.assertRaises(TypeError, lambda: list(mock2))
michael@0 67
michael@0 68
michael@0 69 def test_repr(self):
michael@0 70 mock = Mock()
michael@0 71 self.assertEqual(repr(mock), "<Mock id='%s'>" % id(mock))
michael@0 72 mock.__repr__ = lambda s: 'foo'
michael@0 73 self.assertEqual(repr(mock), 'foo')
michael@0 74
michael@0 75
michael@0 76 def test_str(self):
michael@0 77 mock = Mock()
michael@0 78 self.assertEqual(str(mock), object.__str__(mock))
michael@0 79 mock.__str__ = lambda s: 'foo'
michael@0 80 self.assertEqual(str(mock), 'foo')
michael@0 81
michael@0 82
michael@0 83 @unittest2.skipIf(inPy3k, "no unicode in Python 3")
michael@0 84 def test_unicode(self):
michael@0 85 mock = Mock()
michael@0 86 self.assertEqual(unicode(mock), unicode(str(mock)))
michael@0 87
michael@0 88 mock.__unicode__ = lambda s: unicode('foo')
michael@0 89 self.assertEqual(unicode(mock), unicode('foo'))
michael@0 90
michael@0 91
michael@0 92 def test_dict_methods(self):
michael@0 93 mock = Mock()
michael@0 94
michael@0 95 self.assertRaises(TypeError, lambda: mock['foo'])
michael@0 96 def _del():
michael@0 97 del mock['foo']
michael@0 98 def _set():
michael@0 99 mock['foo'] = 3
michael@0 100 self.assertRaises(TypeError, _del)
michael@0 101 self.assertRaises(TypeError, _set)
michael@0 102
michael@0 103 _dict = {}
michael@0 104 def getitem(s, name):
michael@0 105 return _dict[name]
michael@0 106 def setitem(s, name, value):
michael@0 107 _dict[name] = value
michael@0 108 def delitem(s, name):
michael@0 109 del _dict[name]
michael@0 110
michael@0 111 mock.__setitem__ = setitem
michael@0 112 mock.__getitem__ = getitem
michael@0 113 mock.__delitem__ = delitem
michael@0 114
michael@0 115 self.assertRaises(KeyError, lambda: mock['foo'])
michael@0 116 mock['foo'] = 'bar'
michael@0 117 self.assertEqual(_dict, {'foo': 'bar'})
michael@0 118 self.assertEqual(mock['foo'], 'bar')
michael@0 119 del mock['foo']
michael@0 120 self.assertEqual(_dict, {})
michael@0 121
michael@0 122
michael@0 123 def test_numeric(self):
michael@0 124 original = mock = Mock()
michael@0 125 mock.value = 0
michael@0 126
michael@0 127 self.assertRaises(TypeError, lambda: mock + 3)
michael@0 128
michael@0 129 def add(self, other):
michael@0 130 mock.value += other
michael@0 131 return self
michael@0 132 mock.__add__ = add
michael@0 133 self.assertEqual(mock + 3, mock)
michael@0 134 self.assertEqual(mock.value, 3)
michael@0 135
michael@0 136 del mock.__add__
michael@0 137 def iadd(mock):
michael@0 138 mock += 3
michael@0 139 self.assertRaises(TypeError, iadd, mock)
michael@0 140 mock.__iadd__ = add
michael@0 141 mock += 6
michael@0 142 self.assertEqual(mock, original)
michael@0 143 self.assertEqual(mock.value, 9)
michael@0 144
michael@0 145 self.assertRaises(TypeError, lambda: 3 + mock)
michael@0 146 mock.__radd__ = add
michael@0 147 self.assertEqual(7 + mock, mock)
michael@0 148 self.assertEqual(mock.value, 16)
michael@0 149
michael@0 150
michael@0 151 @unittest2.skipIf(inPy3k, 'no truediv in Python 3')
michael@0 152 def test_truediv(self):
michael@0 153 mock = MagicMock()
michael@0 154 mock.__truediv__.return_value = 6
michael@0 155
michael@0 156 context = {'mock': mock}
michael@0 157 code = 'from __future__ import division\nresult = mock / 7\n'
michael@0 158 exec(code, context)
michael@0 159 self.assertEqual(context['result'], 6)
michael@0 160
michael@0 161 mock.__rtruediv__.return_value = 3
michael@0 162 code = 'from __future__ import division\nresult = 2 / mock\n'
michael@0 163 exec(code, context)
michael@0 164 self.assertEqual(context['result'], 3)
michael@0 165
michael@0 166
michael@0 167 @unittest2.skipIf(not inPy3k, 'truediv is available in Python 2')
michael@0 168 def test_no_truediv(self):
michael@0 169 self.assertRaises(
michael@0 170 AttributeError, getattr, MagicMock(), '__truediv__'
michael@0 171 )
michael@0 172 self.assertRaises(
michael@0 173 AttributeError, getattr, MagicMock(), '__rtruediv__'
michael@0 174 )
michael@0 175
michael@0 176
michael@0 177 def test_hash(self):
michael@0 178 mock = Mock()
michael@0 179 # test delegation
michael@0 180 self.assertEqual(hash(mock), Mock.__hash__(mock))
michael@0 181
michael@0 182 def _hash(s):
michael@0 183 return 3
michael@0 184 mock.__hash__ = _hash
michael@0 185 self.assertEqual(hash(mock), 3)
michael@0 186
michael@0 187
michael@0 188 def test_nonzero(self):
michael@0 189 m = Mock()
michael@0 190 self.assertTrue(bool(m))
michael@0 191
michael@0 192 nonzero = lambda s: False
michael@0 193 if not inPy3k:
michael@0 194 m.__nonzero__ = nonzero
michael@0 195 else:
michael@0 196 m.__bool__ = nonzero
michael@0 197
michael@0 198 self.assertFalse(bool(m))
michael@0 199
michael@0 200
michael@0 201 def test_comparison(self):
michael@0 202 # note: this test fails with Jython 2.5.1 due to a Jython bug
michael@0 203 # it is fixed in jython 2.5.2
michael@0 204 if not inPy3k:
michael@0 205 # incomparable in Python 3
michael@0 206 self. assertEqual(Mock() < 3, object() < 3)
michael@0 207 self. assertEqual(Mock() > 3, object() > 3)
michael@0 208 self. assertEqual(Mock() <= 3, object() <= 3)
michael@0 209 self. assertEqual(Mock() >= 3, object() >= 3)
michael@0 210 else:
michael@0 211 self.assertRaises(TypeError, lambda: MagicMock() < object())
michael@0 212 self.assertRaises(TypeError, lambda: object() < MagicMock())
michael@0 213 self.assertRaises(TypeError, lambda: MagicMock() < MagicMock())
michael@0 214 self.assertRaises(TypeError, lambda: MagicMock() > object())
michael@0 215 self.assertRaises(TypeError, lambda: object() > MagicMock())
michael@0 216 self.assertRaises(TypeError, lambda: MagicMock() > MagicMock())
michael@0 217 self.assertRaises(TypeError, lambda: MagicMock() <= object())
michael@0 218 self.assertRaises(TypeError, lambda: object() <= MagicMock())
michael@0 219 self.assertRaises(TypeError, lambda: MagicMock() <= MagicMock())
michael@0 220 self.assertRaises(TypeError, lambda: MagicMock() >= object())
michael@0 221 self.assertRaises(TypeError, lambda: object() >= MagicMock())
michael@0 222 self.assertRaises(TypeError, lambda: MagicMock() >= MagicMock())
michael@0 223
michael@0 224 mock = Mock()
michael@0 225 def comp(s, o):
michael@0 226 return True
michael@0 227 mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp
michael@0 228 self. assertTrue(mock < 3)
michael@0 229 self. assertTrue(mock > 3)
michael@0 230 self. assertTrue(mock <= 3)
michael@0 231 self. assertTrue(mock >= 3)
michael@0 232
michael@0 233
michael@0 234 def test_equality(self):
michael@0 235 for mock in Mock(), MagicMock():
michael@0 236 self.assertEqual(mock == mock, True)
michael@0 237 self.assertIsInstance(mock == mock, bool)
michael@0 238 self.assertEqual(mock != mock, False)
michael@0 239 self.assertIsInstance(mock != mock, bool)
michael@0 240 self.assertEqual(mock == object(), False)
michael@0 241 self.assertEqual(mock != object(), True)
michael@0 242
michael@0 243 def eq(self, other):
michael@0 244 return other == 3
michael@0 245 mock.__eq__ = eq
michael@0 246 self.assertTrue(mock == 3)
michael@0 247 self.assertFalse(mock == 4)
michael@0 248
michael@0 249 def ne(self, other):
michael@0 250 return other == 3
michael@0 251 mock.__ne__ = ne
michael@0 252 self.assertTrue(mock != 3)
michael@0 253 self.assertFalse(mock != 4)
michael@0 254
michael@0 255 mock = MagicMock()
michael@0 256 mock.__eq__.return_value = True
michael@0 257 self.assertIsInstance(mock == 3, bool)
michael@0 258 self.assertEqual(mock == 3, True)
michael@0 259
michael@0 260 mock.__ne__.return_value = False
michael@0 261 self.assertIsInstance(mock != 3, bool)
michael@0 262 self.assertEqual(mock != 3, False)
michael@0 263
michael@0 264
michael@0 265 def test_len_contains_iter(self):
michael@0 266 mock = Mock()
michael@0 267
michael@0 268 self.assertRaises(TypeError, len, mock)
michael@0 269 self.assertRaises(TypeError, iter, mock)
michael@0 270 self.assertRaises(TypeError, lambda: 'foo' in mock)
michael@0 271
michael@0 272 mock.__len__ = lambda s: 6
michael@0 273 self.assertEqual(len(mock), 6)
michael@0 274
michael@0 275 mock.__contains__ = lambda s, o: o == 3
michael@0 276 self.assertTrue(3 in mock)
michael@0 277 self.assertFalse(6 in mock)
michael@0 278
michael@0 279 mock.__iter__ = lambda s: iter('foobarbaz')
michael@0 280 self.assertEqual(list(mock), list('foobarbaz'))
michael@0 281
michael@0 282
michael@0 283 def test_magicmock(self):
michael@0 284 mock = MagicMock()
michael@0 285
michael@0 286 mock.__iter__.return_value = iter([1, 2, 3])
michael@0 287 self.assertEqual(list(mock), [1, 2, 3])
michael@0 288
michael@0 289 name = '__nonzero__'
michael@0 290 other = '__bool__'
michael@0 291 if inPy3k:
michael@0 292 name, other = other, name
michael@0 293 getattr(mock, name).return_value = False
michael@0 294 self.assertFalse(hasattr(mock, other))
michael@0 295 self.assertFalse(bool(mock))
michael@0 296
michael@0 297 for entry in _magics:
michael@0 298 self.assertTrue(hasattr(mock, entry))
michael@0 299 self.assertFalse(hasattr(mock, '__imaginery__'))
michael@0 300
michael@0 301
michael@0 302 def test_magic_mock_equality(self):
michael@0 303 mock = MagicMock()
michael@0 304 self.assertIsInstance(mock == object(), bool)
michael@0 305 self.assertIsInstance(mock != object(), bool)
michael@0 306
michael@0 307 self.assertEqual(mock == object(), False)
michael@0 308 self.assertEqual(mock != object(), True)
michael@0 309 self.assertEqual(mock == mock, True)
michael@0 310 self.assertEqual(mock != mock, False)
michael@0 311
michael@0 312
michael@0 313 def test_magicmock_defaults(self):
michael@0 314 mock = MagicMock()
michael@0 315 self.assertEqual(int(mock), 1)
michael@0 316 self.assertEqual(complex(mock), 1j)
michael@0 317 self.assertEqual(float(mock), 1.0)
michael@0 318 self.assertEqual(long(mock), long(1))
michael@0 319 self.assertNotIn(object(), mock)
michael@0 320 self.assertEqual(len(mock), 0)
michael@0 321 self.assertEqual(list(mock), [])
michael@0 322 self.assertEqual(hash(mock), object.__hash__(mock))
michael@0 323 self.assertEqual(str(mock), object.__str__(mock))
michael@0 324 self.assertEqual(unicode(mock), object.__str__(mock))
michael@0 325 self.assertIsInstance(unicode(mock), unicode)
michael@0 326 self.assertTrue(bool(mock))
michael@0 327 if not inPy3k:
michael@0 328 self.assertEqual(oct(mock), '1')
michael@0 329 else:
michael@0 330 # in Python 3 oct and hex use __index__
michael@0 331 # so these tests are for __index__ in py3k
michael@0 332 self.assertEqual(oct(mock), '0o1')
michael@0 333 self.assertEqual(hex(mock), '0x1')
michael@0 334 # how to test __sizeof__ ?
michael@0 335
michael@0 336
michael@0 337 @unittest2.skipIf(inPy3k, "no __cmp__ in Python 3")
michael@0 338 def test_non_default_magic_methods(self):
michael@0 339 mock = MagicMock()
michael@0 340 self.assertRaises(AttributeError, lambda: mock.__cmp__)
michael@0 341
michael@0 342 mock = Mock()
michael@0 343 mock.__cmp__ = lambda s, o: 0
michael@0 344
michael@0 345 self.assertEqual(mock, object())
michael@0 346
michael@0 347
michael@0 348 def test_magic_methods_and_spec(self):
michael@0 349 class Iterable(object):
michael@0 350 def __iter__(self):
michael@0 351 pass
michael@0 352
michael@0 353 mock = Mock(spec=Iterable)
michael@0 354 self.assertRaises(AttributeError, lambda: mock.__iter__)
michael@0 355
michael@0 356 mock.__iter__ = Mock(return_value=iter([]))
michael@0 357 self.assertEqual(list(mock), [])
michael@0 358
michael@0 359 class NonIterable(object):
michael@0 360 pass
michael@0 361 mock = Mock(spec=NonIterable)
michael@0 362 self.assertRaises(AttributeError, lambda: mock.__iter__)
michael@0 363
michael@0 364 def set_int():
michael@0 365 mock.__int__ = Mock(return_value=iter([]))
michael@0 366 self.assertRaises(AttributeError, set_int)
michael@0 367
michael@0 368 mock = MagicMock(spec=Iterable)
michael@0 369 self.assertEqual(list(mock), [])
michael@0 370 self.assertRaises(AttributeError, set_int)
michael@0 371
michael@0 372
michael@0 373 def test_magic_methods_and_spec_set(self):
michael@0 374 class Iterable(object):
michael@0 375 def __iter__(self):
michael@0 376 pass
michael@0 377
michael@0 378 mock = Mock(spec_set=Iterable)
michael@0 379 self.assertRaises(AttributeError, lambda: mock.__iter__)
michael@0 380
michael@0 381 mock.__iter__ = Mock(return_value=iter([]))
michael@0 382 self.assertEqual(list(mock), [])
michael@0 383
michael@0 384 class NonIterable(object):
michael@0 385 pass
michael@0 386 mock = Mock(spec_set=NonIterable)
michael@0 387 self.assertRaises(AttributeError, lambda: mock.__iter__)
michael@0 388
michael@0 389 def set_int():
michael@0 390 mock.__int__ = Mock(return_value=iter([]))
michael@0 391 self.assertRaises(AttributeError, set_int)
michael@0 392
michael@0 393 mock = MagicMock(spec_set=Iterable)
michael@0 394 self.assertEqual(list(mock), [])
michael@0 395 self.assertRaises(AttributeError, set_int)
michael@0 396
michael@0 397
michael@0 398 def test_setting_unsupported_magic_method(self):
michael@0 399 mock = MagicMock()
michael@0 400 def set_setattr():
michael@0 401 mock.__setattr__ = lambda self, name: None
michael@0 402 self.assertRaisesRegexp(AttributeError,
michael@0 403 "Attempting to set unsupported magic method '__setattr__'.",
michael@0 404 set_setattr
michael@0 405 )
michael@0 406
michael@0 407
michael@0 408 def test_attributes_and_return_value(self):
michael@0 409 mock = MagicMock()
michael@0 410 attr = mock.foo
michael@0 411 def _get_type(obj):
michael@0 412 # the type of every mock (or magicmock) is a custom subclass
michael@0 413 # so the real type is the second in the mro
michael@0 414 return type(obj).__mro__[1]
michael@0 415 self.assertEqual(_get_type(attr), MagicMock)
michael@0 416
michael@0 417 returned = mock()
michael@0 418 self.assertEqual(_get_type(returned), MagicMock)
michael@0 419
michael@0 420
michael@0 421 def test_magic_methods_are_magic_mocks(self):
michael@0 422 mock = MagicMock()
michael@0 423 self.assertIsInstance(mock.__getitem__, MagicMock)
michael@0 424
michael@0 425 mock[1][2].__getitem__.return_value = 3
michael@0 426 self.assertEqual(mock[1][2][3], 3)
michael@0 427
michael@0 428
michael@0 429 def test_magic_method_reset_mock(self):
michael@0 430 mock = MagicMock()
michael@0 431 str(mock)
michael@0 432 self.assertTrue(mock.__str__.called)
michael@0 433 mock.reset_mock()
michael@0 434 self.assertFalse(mock.__str__.called)
michael@0 435
michael@0 436
michael@0 437 @unittest2.skipUnless(sys.version_info[:2] >= (2, 6),
michael@0 438 "__dir__ not available until Python 2.6 or later")
michael@0 439 def test_dir(self):
michael@0 440 # overriding the default implementation
michael@0 441 for mock in Mock(), MagicMock():
michael@0 442 def _dir(self):
michael@0 443 return ['foo']
michael@0 444 mock.__dir__ = _dir
michael@0 445 self.assertEqual(dir(mock), ['foo'])
michael@0 446
michael@0 447
michael@0 448 @unittest2.skipIf('PyPy' in sys.version, "This fails differently on pypy")
michael@0 449 def test_bound_methods(self):
michael@0 450 m = Mock()
michael@0 451
michael@0 452 # XXXX should this be an expected failure instead?
michael@0 453
michael@0 454 # this seems like it should work, but is hard to do without introducing
michael@0 455 # other api inconsistencies. Failure message could be better though.
michael@0 456 m.__iter__ = [3].__iter__
michael@0 457 self.assertRaises(TypeError, iter, m)
michael@0 458
michael@0 459
michael@0 460 def test_magic_method_type(self):
michael@0 461 class Foo(MagicMock):
michael@0 462 pass
michael@0 463
michael@0 464 foo = Foo()
michael@0 465 self.assertIsInstance(foo.__int__, Foo)
michael@0 466
michael@0 467
michael@0 468 def test_descriptor_from_class(self):
michael@0 469 m = MagicMock()
michael@0 470 type(m).__str__.return_value = 'foo'
michael@0 471 self.assertEqual(str(m), 'foo')
michael@0 472
michael@0 473
michael@0 474 def test_iterable_as_iter_return_value(self):
michael@0 475 m = MagicMock()
michael@0 476 m.__iter__.return_value = [1, 2, 3]
michael@0 477 self.assertEqual(list(m), [1, 2, 3])
michael@0 478 self.assertEqual(list(m), [1, 2, 3])
michael@0 479
michael@0 480 m.__iter__.return_value = iter([4, 5, 6])
michael@0 481 self.assertEqual(list(m), [4, 5, 6])
michael@0 482 self.assertEqual(list(m), [])
michael@0 483
michael@0 484
michael@0 485 if __name__ == '__main__':
michael@0 486 unittest2.main()

mercurial