michael@0: # Copyright (C) 2007-2012 Michael Foord & the mock team michael@0: # E-mail: fuzzyman AT voidspace DOT org DOT uk michael@0: # http://www.voidspace.org.uk/python/mock/ michael@0: michael@0: from tests.support import is_instance, unittest2, X, SomeClass michael@0: michael@0: from mock import ( michael@0: Mock, MagicMock, NonCallableMagicMock, michael@0: NonCallableMock, patch, create_autospec, michael@0: CallableMixin michael@0: ) michael@0: michael@0: michael@0: michael@0: class TestCallable(unittest2.TestCase): michael@0: michael@0: def assertNotCallable(self, mock): michael@0: self.assertTrue(is_instance(mock, NonCallableMagicMock)) michael@0: self.assertFalse(is_instance(mock, CallableMixin)) michael@0: michael@0: michael@0: def test_non_callable(self): michael@0: for mock in NonCallableMagicMock(), NonCallableMock(): michael@0: self.assertRaises(TypeError, mock) michael@0: self.assertFalse(hasattr(mock, '__call__')) michael@0: self.assertIn(mock.__class__.__name__, repr(mock)) michael@0: michael@0: michael@0: def test_heirarchy(self): michael@0: self.assertTrue(issubclass(MagicMock, Mock)) michael@0: self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock)) michael@0: michael@0: michael@0: def test_attributes(self): michael@0: one = NonCallableMock() michael@0: self.assertTrue(issubclass(type(one.one), Mock)) michael@0: michael@0: two = NonCallableMagicMock() michael@0: self.assertTrue(issubclass(type(two.two), MagicMock)) michael@0: michael@0: michael@0: def test_subclasses(self): michael@0: class MockSub(Mock): michael@0: pass michael@0: michael@0: one = MockSub() michael@0: self.assertTrue(issubclass(type(one.one), MockSub)) michael@0: michael@0: class MagicSub(MagicMock): michael@0: pass michael@0: michael@0: two = MagicSub() michael@0: self.assertTrue(issubclass(type(two.two), MagicSub)) michael@0: michael@0: michael@0: def test_patch_spec(self): michael@0: patcher = patch('%s.X' % __name__, spec=True) michael@0: mock = patcher.start() michael@0: self.addCleanup(patcher.stop) michael@0: michael@0: instance = mock() michael@0: mock.assert_called_once_with() michael@0: michael@0: self.assertNotCallable(instance) michael@0: self.assertRaises(TypeError, instance) michael@0: michael@0: michael@0: def test_patch_spec_set(self): michael@0: patcher = patch('%s.X' % __name__, spec_set=True) michael@0: mock = patcher.start() michael@0: self.addCleanup(patcher.stop) michael@0: michael@0: instance = mock() michael@0: mock.assert_called_once_with() michael@0: michael@0: self.assertNotCallable(instance) michael@0: self.assertRaises(TypeError, instance) michael@0: michael@0: michael@0: def test_patch_spec_instance(self): michael@0: patcher = patch('%s.X' % __name__, spec=X()) michael@0: mock = patcher.start() michael@0: self.addCleanup(patcher.stop) michael@0: michael@0: self.assertNotCallable(mock) michael@0: self.assertRaises(TypeError, mock) michael@0: michael@0: michael@0: def test_patch_spec_set_instance(self): michael@0: patcher = patch('%s.X' % __name__, spec_set=X()) michael@0: mock = patcher.start() michael@0: self.addCleanup(patcher.stop) michael@0: michael@0: self.assertNotCallable(mock) michael@0: self.assertRaises(TypeError, mock) michael@0: michael@0: michael@0: def test_patch_spec_callable_class(self): michael@0: class CallableX(X): michael@0: def __call__(self): michael@0: pass michael@0: michael@0: class Sub(CallableX): michael@0: pass michael@0: michael@0: class Multi(SomeClass, Sub): michael@0: pass michael@0: michael@0: class OldStyle: michael@0: def __call__(self): michael@0: pass michael@0: michael@0: class OldStyleSub(OldStyle): michael@0: pass michael@0: michael@0: for arg in 'spec', 'spec_set': michael@0: for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub: michael@0: patcher = patch('%s.X' % __name__, **{arg: Klass}) michael@0: mock = patcher.start() michael@0: michael@0: try: michael@0: instance = mock() michael@0: mock.assert_called_once_with() michael@0: michael@0: self.assertTrue(is_instance(instance, MagicMock)) michael@0: # inherited spec michael@0: self.assertRaises(AttributeError, getattr, instance, michael@0: 'foobarbaz') michael@0: michael@0: result = instance() michael@0: # instance is callable, result has no spec michael@0: instance.assert_called_once_with() michael@0: michael@0: result(3, 2, 1) michael@0: result.assert_called_once_with(3, 2, 1) michael@0: result.foo(3, 2, 1) michael@0: result.foo.assert_called_once_with(3, 2, 1) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_create_autopsec(self): michael@0: mock = create_autospec(X) michael@0: instance = mock() michael@0: self.assertRaises(TypeError, instance) michael@0: michael@0: mock = create_autospec(X()) michael@0: self.assertRaises(TypeError, mock) michael@0: michael@0: michael@0: def test_create_autospec_instance(self): michael@0: mock = create_autospec(SomeClass, instance=True) michael@0: michael@0: self.assertRaises(TypeError, mock) michael@0: mock.wibble() michael@0: mock.wibble.assert_called_once_with() michael@0: michael@0: self.assertRaises(TypeError, mock.wibble, 'some', 'args')