Michael Foord | 1e68bec | 2012-03-03 22:24:30 +0000 | [diff] [blame] | 1 | # 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 | |
| 5 | from tests.support import is_instance, unittest2, X, SomeClass |
| 6 | |
| 7 | from mock import ( |
| 8 | Mock, MagicMock, NonCallableMagicMock, |
| 9 | NonCallableMock, patch, create_autospec, |
| 10 | CallableMixin |
| 11 | ) |
| 12 | |
| 13 | |
| 14 | |
| 15 | class TestCallable(unittest2.TestCase): |
| 16 | |
| 17 | def assertNotCallable(self, mock): |
| 18 | self.assertTrue(is_instance(mock, NonCallableMagicMock)) |
| 19 | self.assertFalse(is_instance(mock, CallableMixin)) |
| 20 | |
| 21 | |
| 22 | def test_non_callable(self): |
| 23 | for mock in NonCallableMagicMock(), NonCallableMock(): |
| 24 | self.assertRaises(TypeError, mock) |
| 25 | self.assertFalse(hasattr(mock, '__call__')) |
| 26 | self.assertIn(mock.__class__.__name__, repr(mock)) |
| 27 | |
| 28 | |
| 29 | def test_heirarchy(self): |
| 30 | self.assertTrue(issubclass(MagicMock, Mock)) |
| 31 | self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock)) |
| 32 | |
| 33 | |
| 34 | def test_attributes(self): |
| 35 | one = NonCallableMock() |
| 36 | self.assertTrue(issubclass(type(one.one), Mock)) |
| 37 | |
| 38 | two = NonCallableMagicMock() |
| 39 | self.assertTrue(issubclass(type(two.two), MagicMock)) |
| 40 | |
| 41 | |
| 42 | def test_subclasses(self): |
| 43 | class MockSub(Mock): |
| 44 | pass |
| 45 | |
| 46 | one = MockSub() |
| 47 | self.assertTrue(issubclass(type(one.one), MockSub)) |
| 48 | |
| 49 | class MagicSub(MagicMock): |
| 50 | pass |
| 51 | |
| 52 | two = MagicSub() |
| 53 | self.assertTrue(issubclass(type(two.two), MagicSub)) |
| 54 | |
| 55 | |
| 56 | def test_patch_spec(self): |
| 57 | patcher = patch('%s.X' % __name__, spec=True) |
| 58 | mock = patcher.start() |
| 59 | self.addCleanup(patcher.stop) |
| 60 | |
| 61 | instance = mock() |
| 62 | mock.assert_called_once_with() |
| 63 | |
| 64 | self.assertNotCallable(instance) |
| 65 | self.assertRaises(TypeError, instance) |
| 66 | |
| 67 | |
| 68 | def test_patch_spec_set(self): |
| 69 | patcher = patch('%s.X' % __name__, spec_set=True) |
| 70 | mock = patcher.start() |
| 71 | self.addCleanup(patcher.stop) |
| 72 | |
| 73 | instance = mock() |
| 74 | mock.assert_called_once_with() |
| 75 | |
| 76 | self.assertNotCallable(instance) |
| 77 | self.assertRaises(TypeError, instance) |
| 78 | |
| 79 | |
| 80 | def test_patch_spec_instance(self): |
| 81 | patcher = patch('%s.X' % __name__, spec=X()) |
| 82 | mock = patcher.start() |
| 83 | self.addCleanup(patcher.stop) |
| 84 | |
| 85 | self.assertNotCallable(mock) |
| 86 | self.assertRaises(TypeError, mock) |
| 87 | |
| 88 | |
| 89 | def test_patch_spec_set_instance(self): |
| 90 | patcher = patch('%s.X' % __name__, spec_set=X()) |
| 91 | mock = patcher.start() |
| 92 | self.addCleanup(patcher.stop) |
| 93 | |
| 94 | self.assertNotCallable(mock) |
| 95 | self.assertRaises(TypeError, mock) |
| 96 | |
| 97 | |
| 98 | def test_patch_spec_callable_class(self): |
| 99 | class CallableX(X): |
| 100 | def __call__(self): |
| 101 | pass |
| 102 | |
| 103 | class Sub(CallableX): |
| 104 | pass |
| 105 | |
| 106 | class Multi(SomeClass, Sub): |
| 107 | pass |
| 108 | |
| 109 | class OldStyle: |
| 110 | def __call__(self): |
| 111 | pass |
| 112 | |
| 113 | class OldStyleSub(OldStyle): |
| 114 | pass |
| 115 | |
| 116 | for arg in 'spec', 'spec_set': |
| 117 | for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub: |
| 118 | patcher = patch('%s.X' % __name__, **{arg: Klass}) |
| 119 | mock = patcher.start() |
| 120 | |
| 121 | try: |
| 122 | instance = mock() |
| 123 | mock.assert_called_once_with() |
| 124 | |
| 125 | self.assertTrue(is_instance(instance, MagicMock)) |
| 126 | # inherited spec |
| 127 | self.assertRaises(AttributeError, getattr, instance, |
| 128 | 'foobarbaz') |
| 129 | |
| 130 | result = instance() |
| 131 | # instance is callable, result has no spec |
| 132 | instance.assert_called_once_with() |
| 133 | |
| 134 | result(3, 2, 1) |
| 135 | result.assert_called_once_with(3, 2, 1) |
| 136 | result.foo(3, 2, 1) |
| 137 | result.foo.assert_called_once_with(3, 2, 1) |
| 138 | finally: |
| 139 | patcher.stop() |
| 140 | |
| 141 | |
| 142 | def test_create_autopsec(self): |
| 143 | mock = create_autospec(X) |
| 144 | instance = mock() |
| 145 | self.assertRaises(TypeError, instance) |
| 146 | |
| 147 | mock = create_autospec(X()) |
| 148 | self.assertRaises(TypeError, mock) |
| 149 | |
| 150 | |
| 151 | def test_create_autospec_instance(self): |
| 152 | mock = create_autospec(SomeClass, instance=True) |
| 153 | |
| 154 | self.assertRaises(TypeError, mock) |
| 155 | mock.wibble() |
| 156 | mock.wibble.assert_called_once_with() |
| 157 | |
| 158 | self.assertRaises(TypeError, mock.wibble, 'some', 'args') |