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