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: import os michael@0: import sys michael@0: michael@0: from tests import support michael@0: from tests.support import unittest2, inPy3k, SomeClass, is_instance, callable michael@0: michael@0: from mock import ( michael@0: NonCallableMock, CallableMixin, patch, sentinel, michael@0: MagicMock, Mock, NonCallableMagicMock, patch, _patch, michael@0: DEFAULT, call, _get_target michael@0: ) michael@0: michael@0: builtin_string = '__builtin__' michael@0: if inPy3k: michael@0: builtin_string = 'builtins' michael@0: unicode = str michael@0: michael@0: PTModule = sys.modules[__name__] michael@0: MODNAME = '%s.PTModule' % __name__ michael@0: michael@0: michael@0: def _get_proxy(obj, get_only=True): michael@0: class Proxy(object): michael@0: def __getattr__(self, name): michael@0: return getattr(obj, name) michael@0: if not get_only: michael@0: def __setattr__(self, name, value): michael@0: setattr(obj, name, value) michael@0: def __delattr__(self, name): michael@0: delattr(obj, name) michael@0: Proxy.__setattr__ = __setattr__ michael@0: Proxy.__delattr__ = __delattr__ michael@0: return Proxy() michael@0: michael@0: michael@0: # for use in the test michael@0: something = sentinel.Something michael@0: something_else = sentinel.SomethingElse michael@0: michael@0: michael@0: class Foo(object): michael@0: def __init__(self, a): michael@0: pass michael@0: def f(self, a): michael@0: pass michael@0: def g(self): michael@0: pass michael@0: foo = 'bar' michael@0: michael@0: class Bar(object): michael@0: def a(self): michael@0: pass michael@0: michael@0: foo_name = '%s.Foo' % __name__ michael@0: michael@0: michael@0: def function(a, b=Foo): michael@0: pass michael@0: michael@0: michael@0: class Container(object): michael@0: def __init__(self): michael@0: self.values = {} michael@0: michael@0: def __getitem__(self, name): michael@0: return self.values[name] michael@0: michael@0: def __setitem__(self, name, value): michael@0: self.values[name] = value michael@0: michael@0: def __delitem__(self, name): michael@0: del self.values[name] michael@0: michael@0: def __iter__(self): michael@0: return iter(self.values) michael@0: michael@0: michael@0: michael@0: class PatchTest(unittest2.TestCase): michael@0: michael@0: def assertNotCallable(self, obj, magic=True): michael@0: MockClass = NonCallableMagicMock michael@0: if not magic: michael@0: MockClass = NonCallableMock michael@0: michael@0: self.assertRaises(TypeError, obj) michael@0: self.assertTrue(is_instance(obj, MockClass)) michael@0: self.assertFalse(is_instance(obj, CallableMixin)) michael@0: michael@0: michael@0: def test_single_patchobject(self): michael@0: class Something(object): michael@0: attribute = sentinel.Original michael@0: michael@0: @patch.object(Something, 'attribute', sentinel.Patched) michael@0: def test(): michael@0: self.assertEqual(Something.attribute, sentinel.Patched, "unpatched") michael@0: michael@0: test() michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_patchobject_with_none(self): michael@0: class Something(object): michael@0: attribute = sentinel.Original michael@0: michael@0: @patch.object(Something, 'attribute', None) michael@0: def test(): michael@0: self.assertIsNone(Something.attribute, "unpatched") michael@0: michael@0: test() michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_multiple_patchobject(self): michael@0: class Something(object): michael@0: attribute = sentinel.Original michael@0: next_attribute = sentinel.Original2 michael@0: michael@0: @patch.object(Something, 'attribute', sentinel.Patched) michael@0: @patch.object(Something, 'next_attribute', sentinel.Patched2) michael@0: def test(): michael@0: self.assertEqual(Something.attribute, sentinel.Patched, michael@0: "unpatched") michael@0: self.assertEqual(Something.next_attribute, sentinel.Patched2, michael@0: "unpatched") michael@0: michael@0: test() michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "patch not restored") michael@0: self.assertEqual(Something.next_attribute, sentinel.Original2, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_object_lookup_is_quite_lazy(self): michael@0: global something michael@0: original = something michael@0: @patch('%s.something' % __name__, sentinel.Something2) michael@0: def test(): michael@0: pass michael@0: michael@0: try: michael@0: something = sentinel.replacement_value michael@0: test() michael@0: self.assertEqual(something, sentinel.replacement_value) michael@0: finally: michael@0: something = original michael@0: michael@0: michael@0: def test_patch(self): michael@0: @patch('%s.something' % __name__, sentinel.Something2) michael@0: def test(): michael@0: self.assertEqual(PTModule.something, sentinel.Something2, michael@0: "unpatched") michael@0: michael@0: test() michael@0: self.assertEqual(PTModule.something, sentinel.Something, michael@0: "patch not restored") michael@0: michael@0: @patch('%s.something' % __name__, sentinel.Something2) michael@0: @patch('%s.something_else' % __name__, sentinel.SomethingElse) michael@0: def test(): michael@0: self.assertEqual(PTModule.something, sentinel.Something2, michael@0: "unpatched") michael@0: self.assertEqual(PTModule.something_else, sentinel.SomethingElse, michael@0: "unpatched") michael@0: michael@0: self.assertEqual(PTModule.something, sentinel.Something, michael@0: "patch not restored") michael@0: self.assertEqual(PTModule.something_else, sentinel.SomethingElse, michael@0: "patch not restored") michael@0: michael@0: # Test the patching and restoring works a second time michael@0: test() michael@0: michael@0: self.assertEqual(PTModule.something, sentinel.Something, michael@0: "patch not restored") michael@0: self.assertEqual(PTModule.something_else, sentinel.SomethingElse, michael@0: "patch not restored") michael@0: michael@0: mock = Mock() michael@0: mock.return_value = sentinel.Handle michael@0: @patch('%s.open' % builtin_string, mock) michael@0: def test(): michael@0: self.assertEqual(open('filename', 'r'), sentinel.Handle, michael@0: "open not patched") michael@0: test() michael@0: test() michael@0: michael@0: self.assertNotEqual(open, mock, "patch not restored") michael@0: michael@0: michael@0: def test_patch_class_attribute(self): michael@0: @patch('%s.SomeClass.class_attribute' % __name__, michael@0: sentinel.ClassAttribute) michael@0: def test(): michael@0: self.assertEqual(PTModule.SomeClass.class_attribute, michael@0: sentinel.ClassAttribute, "unpatched") michael@0: test() michael@0: michael@0: self.assertIsNone(PTModule.SomeClass.class_attribute, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_patchobject_with_default_mock(self): michael@0: class Test(object): michael@0: something = sentinel.Original michael@0: something2 = sentinel.Original2 michael@0: michael@0: @patch.object(Test, 'something') michael@0: def test(mock): michael@0: self.assertEqual(mock, Test.something, michael@0: "Mock not passed into test function") michael@0: self.assertIsInstance(mock, MagicMock, michael@0: "patch with two arguments did not create a mock") michael@0: michael@0: test() michael@0: michael@0: @patch.object(Test, 'something') michael@0: @patch.object(Test, 'something2') michael@0: def test(this1, this2, mock1, mock2): michael@0: self.assertEqual(this1, sentinel.this1, michael@0: "Patched function didn't receive initial argument") michael@0: self.assertEqual(this2, sentinel.this2, michael@0: "Patched function didn't receive second argument") michael@0: self.assertEqual(mock1, Test.something2, michael@0: "Mock not passed into test function") michael@0: self.assertEqual(mock2, Test.something, michael@0: "Second Mock not passed into test function") michael@0: self.assertIsInstance(mock2, MagicMock, michael@0: "patch with two arguments did not create a mock") michael@0: self.assertIsInstance(mock2, MagicMock, michael@0: "patch with two arguments did not create a mock") michael@0: michael@0: # A hack to test that new mocks are passed the second time michael@0: self.assertNotEqual(outerMock1, mock1, "unexpected value for mock1") michael@0: self.assertNotEqual(outerMock2, mock2, "unexpected value for mock1") michael@0: return mock1, mock2 michael@0: michael@0: outerMock1 = outerMock2 = None michael@0: outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2) michael@0: michael@0: # Test that executing a second time creates new mocks michael@0: test(sentinel.this1, sentinel.this2) michael@0: michael@0: michael@0: def test_patch_with_spec(self): michael@0: @patch('%s.SomeClass' % __name__, spec=SomeClass) michael@0: def test(MockSomeClass): michael@0: self.assertEqual(SomeClass, MockSomeClass) michael@0: self.assertTrue(is_instance(SomeClass.wibble, MagicMock)) michael@0: self.assertRaises(AttributeError, lambda: SomeClass.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patchobject_with_spec(self): michael@0: @patch.object(SomeClass, 'class_attribute', spec=SomeClass) michael@0: def test(MockAttribute): michael@0: self.assertEqual(SomeClass.class_attribute, MockAttribute) michael@0: self.assertTrue(is_instance(SomeClass.class_attribute.wibble, michael@0: MagicMock)) michael@0: self.assertRaises(AttributeError, michael@0: lambda: SomeClass.class_attribute.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patch_with_spec_as_list(self): michael@0: @patch('%s.SomeClass' % __name__, spec=['wibble']) michael@0: def test(MockSomeClass): michael@0: self.assertEqual(SomeClass, MockSomeClass) michael@0: self.assertTrue(is_instance(SomeClass.wibble, MagicMock)) michael@0: self.assertRaises(AttributeError, lambda: SomeClass.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patchobject_with_spec_as_list(self): michael@0: @patch.object(SomeClass, 'class_attribute', spec=['wibble']) michael@0: def test(MockAttribute): michael@0: self.assertEqual(SomeClass.class_attribute, MockAttribute) michael@0: self.assertTrue(is_instance(SomeClass.class_attribute.wibble, michael@0: MagicMock)) michael@0: self.assertRaises(AttributeError, michael@0: lambda: SomeClass.class_attribute.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_nested_patch_with_spec_as_list(self): michael@0: # regression test for nested decorators michael@0: @patch('%s.open' % builtin_string) michael@0: @patch('%s.SomeClass' % __name__, spec=['wibble']) michael@0: def test(MockSomeClass, MockOpen): michael@0: self.assertEqual(SomeClass, MockSomeClass) michael@0: self.assertTrue(is_instance(SomeClass.wibble, MagicMock)) michael@0: self.assertRaises(AttributeError, lambda: SomeClass.not_wibble) michael@0: test() michael@0: michael@0: michael@0: def test_patch_with_spec_as_boolean(self): michael@0: @patch('%s.SomeClass' % __name__, spec=True) michael@0: def test(MockSomeClass): michael@0: self.assertEqual(SomeClass, MockSomeClass) michael@0: # Should not raise attribute error michael@0: MockSomeClass.wibble michael@0: michael@0: self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patch_object_with_spec_as_boolean(self): michael@0: @patch.object(PTModule, 'SomeClass', spec=True) michael@0: def test(MockSomeClass): michael@0: self.assertEqual(SomeClass, MockSomeClass) michael@0: # Should not raise attribute error michael@0: MockSomeClass.wibble michael@0: michael@0: self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patch_class_acts_with_spec_is_inherited(self): michael@0: @patch('%s.SomeClass' % __name__, spec=True) michael@0: def test(MockSomeClass): michael@0: self.assertTrue(is_instance(MockSomeClass, MagicMock)) michael@0: instance = MockSomeClass() michael@0: self.assertNotCallable(instance) michael@0: # Should not raise attribute error michael@0: instance.wibble michael@0: michael@0: self.assertRaises(AttributeError, lambda: instance.not_wibble) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patch_with_create_mocks_non_existent_attributes(self): michael@0: @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True) michael@0: def test(): michael@0: self.assertEqual(frooble, sentinel.Frooble) michael@0: michael@0: test() michael@0: self.assertRaises(NameError, lambda: frooble) michael@0: michael@0: michael@0: def test_patchobject_with_create_mocks_non_existent_attributes(self): michael@0: @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True) michael@0: def test(): michael@0: self.assertEqual(SomeClass.frooble, sentinel.Frooble) michael@0: michael@0: test() michael@0: self.assertFalse(hasattr(SomeClass, 'frooble')) michael@0: michael@0: michael@0: def test_patch_wont_create_by_default(self): michael@0: try: michael@0: @patch('%s.frooble' % builtin_string, sentinel.Frooble) michael@0: def test(): michael@0: self.assertEqual(frooble, sentinel.Frooble) michael@0: michael@0: test() michael@0: except AttributeError: michael@0: pass michael@0: else: michael@0: self.fail('Patching non existent attributes should fail') michael@0: michael@0: self.assertRaises(NameError, lambda: frooble) michael@0: michael@0: michael@0: def test_patchobject_wont_create_by_default(self): michael@0: try: michael@0: @patch.object(SomeClass, 'frooble', sentinel.Frooble) michael@0: def test(): michael@0: self.fail('Patching non existent attributes should fail') michael@0: michael@0: test() michael@0: except AttributeError: michael@0: pass michael@0: else: michael@0: self.fail('Patching non existent attributes should fail') michael@0: self.assertFalse(hasattr(SomeClass, 'frooble')) michael@0: michael@0: michael@0: def test_patch_with_static_methods(self): michael@0: class Foo(object): michael@0: @staticmethod michael@0: def woot(): michael@0: return sentinel.Static michael@0: michael@0: @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched)) michael@0: def anonymous(): michael@0: self.assertEqual(Foo.woot(), sentinel.Patched) michael@0: anonymous() michael@0: michael@0: self.assertEqual(Foo.woot(), sentinel.Static) michael@0: michael@0: michael@0: def test_patch_local(self): michael@0: foo = sentinel.Foo michael@0: @patch.object(sentinel, 'Foo', 'Foo') michael@0: def anonymous(): michael@0: self.assertEqual(sentinel.Foo, 'Foo') michael@0: anonymous() michael@0: michael@0: self.assertEqual(sentinel.Foo, foo) michael@0: michael@0: michael@0: def test_patch_slots(self): michael@0: class Foo(object): michael@0: __slots__ = ('Foo',) michael@0: michael@0: foo = Foo() michael@0: foo.Foo = sentinel.Foo michael@0: michael@0: @patch.object(foo, 'Foo', 'Foo') michael@0: def anonymous(): michael@0: self.assertEqual(foo.Foo, 'Foo') michael@0: anonymous() michael@0: michael@0: self.assertEqual(foo.Foo, sentinel.Foo) michael@0: michael@0: michael@0: def test_patchobject_class_decorator(self): michael@0: class Something(object): michael@0: attribute = sentinel.Original michael@0: michael@0: class Foo(object): michael@0: def test_method(other_self): michael@0: self.assertEqual(Something.attribute, sentinel.Patched, michael@0: "unpatched") michael@0: def not_test_method(other_self): michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "non-test method patched") michael@0: michael@0: Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo) michael@0: michael@0: f = Foo() michael@0: f.test_method() michael@0: f.not_test_method() michael@0: michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_patch_class_decorator(self): michael@0: class Something(object): michael@0: attribute = sentinel.Original michael@0: michael@0: class Foo(object): michael@0: def test_method(other_self, mock_something): michael@0: self.assertEqual(PTModule.something, mock_something, michael@0: "unpatched") michael@0: def not_test_method(other_self): michael@0: self.assertEqual(PTModule.something, sentinel.Something, michael@0: "non-test method patched") michael@0: Foo = patch('%s.something' % __name__)(Foo) michael@0: michael@0: f = Foo() michael@0: f.test_method() michael@0: f.not_test_method() michael@0: michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "patch not restored") michael@0: self.assertEqual(PTModule.something, sentinel.Something, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_patchobject_twice(self): michael@0: class Something(object): michael@0: attribute = sentinel.Original michael@0: next_attribute = sentinel.Original2 michael@0: michael@0: @patch.object(Something, 'attribute', sentinel.Patched) michael@0: @patch.object(Something, 'attribute', sentinel.Patched) michael@0: def test(): michael@0: self.assertEqual(Something.attribute, sentinel.Patched, "unpatched") michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(Something.attribute, sentinel.Original, michael@0: "patch not restored") michael@0: michael@0: michael@0: def test_patch_dict(self): michael@0: foo = {'initial': object(), 'other': 'something'} michael@0: original = foo.copy() michael@0: michael@0: @patch.dict(foo) michael@0: def test(): michael@0: foo['a'] = 3 michael@0: del foo['initial'] michael@0: foo['other'] = 'something else' michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo, original) michael@0: michael@0: @patch.dict(foo, {'a': 'b'}) michael@0: def test(): michael@0: self.assertEqual(len(foo), 3) michael@0: self.assertEqual(foo['a'], 'b') michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo, original) michael@0: michael@0: @patch.dict(foo, [('a', 'b')]) michael@0: def test(): michael@0: self.assertEqual(len(foo), 3) michael@0: self.assertEqual(foo['a'], 'b') michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo, original) michael@0: michael@0: michael@0: def test_patch_dict_with_container_object(self): michael@0: foo = Container() michael@0: foo['initial'] = object() michael@0: foo['other'] = 'something' michael@0: michael@0: original = foo.values.copy() michael@0: michael@0: @patch.dict(foo) michael@0: def test(): michael@0: foo['a'] = 3 michael@0: del foo['initial'] michael@0: foo['other'] = 'something else' michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo.values, original) michael@0: michael@0: @patch.dict(foo, {'a': 'b'}) michael@0: def test(): michael@0: self.assertEqual(len(foo.values), 3) michael@0: self.assertEqual(foo['a'], 'b') michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo.values, original) michael@0: michael@0: michael@0: def test_patch_dict_with_clear(self): michael@0: foo = {'initial': object(), 'other': 'something'} michael@0: original = foo.copy() michael@0: michael@0: @patch.dict(foo, clear=True) michael@0: def test(): michael@0: self.assertEqual(foo, {}) michael@0: foo['a'] = 3 michael@0: foo['other'] = 'something else' michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo, original) michael@0: michael@0: @patch.dict(foo, {'a': 'b'}, clear=True) michael@0: def test(): michael@0: self.assertEqual(foo, {'a': 'b'}) michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo, original) michael@0: michael@0: @patch.dict(foo, [('a', 'b')], clear=True) michael@0: def test(): michael@0: self.assertEqual(foo, {'a': 'b'}) michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo, original) michael@0: michael@0: michael@0: def test_patch_dict_with_container_object_and_clear(self): michael@0: foo = Container() michael@0: foo['initial'] = object() michael@0: foo['other'] = 'something' michael@0: michael@0: original = foo.values.copy() michael@0: michael@0: @patch.dict(foo, clear=True) michael@0: def test(): michael@0: self.assertEqual(foo.values, {}) michael@0: foo['a'] = 3 michael@0: foo['other'] = 'something else' michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo.values, original) michael@0: michael@0: @patch.dict(foo, {'a': 'b'}, clear=True) michael@0: def test(): michael@0: self.assertEqual(foo.values, {'a': 'b'}) michael@0: michael@0: test() michael@0: michael@0: self.assertEqual(foo.values, original) michael@0: michael@0: michael@0: def test_name_preserved(self): michael@0: foo = {} michael@0: michael@0: @patch('%s.SomeClass' % __name__, object()) michael@0: @patch('%s.SomeClass' % __name__, object(), autospec=True) michael@0: @patch.object(SomeClass, object()) michael@0: @patch.dict(foo) michael@0: def some_name(): michael@0: pass michael@0: michael@0: self.assertEqual(some_name.__name__, 'some_name') michael@0: michael@0: michael@0: def test_patch_with_exception(self): michael@0: foo = {} michael@0: michael@0: @patch.dict(foo, {'a': 'b'}) michael@0: def test(): michael@0: raise NameError('Konrad') michael@0: try: michael@0: test() michael@0: except NameError: michael@0: pass michael@0: else: michael@0: self.fail('NameError not raised by test') michael@0: michael@0: self.assertEqual(foo, {}) michael@0: michael@0: michael@0: def test_patch_dict_with_string(self): michael@0: @patch.dict('os.environ', {'konrad_delong': 'some value'}) michael@0: def test(): michael@0: self.assertIn('konrad_delong', os.environ) michael@0: michael@0: test() michael@0: michael@0: michael@0: @unittest2.expectedFailure michael@0: def test_patch_descriptor(self): michael@0: # would be some effort to fix this - we could special case the michael@0: # builtin descriptors: classmethod, property, staticmethod michael@0: class Nothing(object): michael@0: foo = None michael@0: michael@0: class Something(object): michael@0: foo = {} michael@0: michael@0: @patch.object(Nothing, 'foo', 2) michael@0: @classmethod michael@0: def klass(cls): michael@0: self.assertIs(cls, Something) michael@0: michael@0: @patch.object(Nothing, 'foo', 2) michael@0: @staticmethod michael@0: def static(arg): michael@0: return arg michael@0: michael@0: @patch.dict(foo) michael@0: @classmethod michael@0: def klass_dict(cls): michael@0: self.assertIs(cls, Something) michael@0: michael@0: @patch.dict(foo) michael@0: @staticmethod michael@0: def static_dict(arg): michael@0: return arg michael@0: michael@0: # these will raise exceptions if patching descriptors is broken michael@0: self.assertEqual(Something.static('f00'), 'f00') michael@0: Something.klass() michael@0: self.assertEqual(Something.static_dict('f00'), 'f00') michael@0: Something.klass_dict() michael@0: michael@0: something = Something() michael@0: self.assertEqual(something.static('f00'), 'f00') michael@0: something.klass() michael@0: self.assertEqual(something.static_dict('f00'), 'f00') michael@0: something.klass_dict() michael@0: michael@0: michael@0: def test_patch_spec_set(self): michael@0: @patch('%s.SomeClass' % __name__, spec_set=SomeClass) michael@0: def test(MockClass): michael@0: MockClass.z = 'foo' michael@0: michael@0: self.assertRaises(AttributeError, test) michael@0: michael@0: @patch.object(support, 'SomeClass', spec_set=SomeClass) michael@0: def test(MockClass): michael@0: MockClass.z = 'foo' michael@0: michael@0: self.assertRaises(AttributeError, test) michael@0: @patch('%s.SomeClass' % __name__, spec_set=True) michael@0: def test(MockClass): michael@0: MockClass.z = 'foo' michael@0: michael@0: self.assertRaises(AttributeError, test) michael@0: michael@0: @patch.object(support, 'SomeClass', spec_set=True) michael@0: def test(MockClass): michael@0: MockClass.z = 'foo' michael@0: michael@0: self.assertRaises(AttributeError, test) michael@0: michael@0: michael@0: def test_spec_set_inherit(self): michael@0: @patch('%s.SomeClass' % __name__, spec_set=True) michael@0: def test(MockClass): michael@0: instance = MockClass() michael@0: instance.z = 'foo' michael@0: michael@0: self.assertRaises(AttributeError, test) michael@0: michael@0: michael@0: def test_patch_start_stop(self): michael@0: original = something michael@0: patcher = patch('%s.something' % __name__) michael@0: self.assertIs(something, original) michael@0: mock = patcher.start() michael@0: try: michael@0: self.assertIsNot(mock, original) michael@0: self.assertIs(something, mock) michael@0: finally: michael@0: patcher.stop() michael@0: self.assertIs(something, original) michael@0: michael@0: michael@0: def test_stop_without_start(self): michael@0: patcher = patch(foo_name, 'bar', 3) michael@0: michael@0: # calling stop without start used to produce a very obscure error michael@0: self.assertRaises(RuntimeError, patcher.stop) michael@0: michael@0: michael@0: def test_patchobject_start_stop(self): michael@0: original = something michael@0: patcher = patch.object(PTModule, 'something', 'foo') michael@0: self.assertIs(something, original) michael@0: replaced = patcher.start() michael@0: try: michael@0: self.assertEqual(replaced, 'foo') michael@0: self.assertIs(something, replaced) michael@0: finally: michael@0: patcher.stop() michael@0: self.assertIs(something, original) michael@0: michael@0: michael@0: def test_patch_dict_start_stop(self): michael@0: d = {'foo': 'bar'} michael@0: original = d.copy() michael@0: patcher = patch.dict(d, [('spam', 'eggs')], clear=True) michael@0: self.assertEqual(d, original) michael@0: michael@0: patcher.start() michael@0: try: michael@0: self.assertEqual(d, {'spam': 'eggs'}) michael@0: finally: michael@0: patcher.stop() michael@0: self.assertEqual(d, original) michael@0: michael@0: michael@0: def test_patch_dict_class_decorator(self): michael@0: this = self michael@0: d = {'spam': 'eggs'} michael@0: original = d.copy() michael@0: michael@0: class Test(object): michael@0: def test_first(self): michael@0: this.assertEqual(d, {'foo': 'bar'}) michael@0: def test_second(self): michael@0: this.assertEqual(d, {'foo': 'bar'}) michael@0: michael@0: Test = patch.dict(d, {'foo': 'bar'}, clear=True)(Test) michael@0: self.assertEqual(d, original) michael@0: michael@0: test = Test() michael@0: michael@0: test.test_first() michael@0: self.assertEqual(d, original) michael@0: michael@0: test.test_second() michael@0: self.assertEqual(d, original) michael@0: michael@0: test = Test() michael@0: michael@0: test.test_first() michael@0: self.assertEqual(d, original) michael@0: michael@0: test.test_second() michael@0: self.assertEqual(d, original) michael@0: michael@0: michael@0: def test_get_only_proxy(self): michael@0: class Something(object): michael@0: foo = 'foo' michael@0: class SomethingElse: michael@0: foo = 'foo' michael@0: michael@0: for thing in Something, SomethingElse, Something(), SomethingElse: michael@0: proxy = _get_proxy(thing) michael@0: michael@0: @patch.object(proxy, 'foo', 'bar') michael@0: def test(): michael@0: self.assertEqual(proxy.foo, 'bar') michael@0: test() michael@0: self.assertEqual(proxy.foo, 'foo') michael@0: self.assertEqual(thing.foo, 'foo') michael@0: self.assertNotIn('foo', proxy.__dict__) michael@0: michael@0: michael@0: def test_get_set_delete_proxy(self): michael@0: class Something(object): michael@0: foo = 'foo' michael@0: class SomethingElse: michael@0: foo = 'foo' michael@0: michael@0: for thing in Something, SomethingElse, Something(), SomethingElse: michael@0: proxy = _get_proxy(Something, get_only=False) michael@0: michael@0: @patch.object(proxy, 'foo', 'bar') michael@0: def test(): michael@0: self.assertEqual(proxy.foo, 'bar') michael@0: test() michael@0: self.assertEqual(proxy.foo, 'foo') michael@0: self.assertEqual(thing.foo, 'foo') michael@0: self.assertNotIn('foo', proxy.__dict__) michael@0: michael@0: michael@0: def test_patch_keyword_args(self): michael@0: kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33, michael@0: 'foo': MagicMock()} michael@0: michael@0: patcher = patch(foo_name, **kwargs) michael@0: mock = patcher.start() michael@0: patcher.stop() michael@0: michael@0: self.assertRaises(KeyError, mock) michael@0: self.assertEqual(mock.foo.bar(), 33) michael@0: self.assertIsInstance(mock.foo, MagicMock) michael@0: michael@0: michael@0: def test_patch_object_keyword_args(self): michael@0: kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33, michael@0: 'foo': MagicMock()} michael@0: michael@0: patcher = patch.object(Foo, 'f', **kwargs) michael@0: mock = patcher.start() michael@0: patcher.stop() michael@0: michael@0: self.assertRaises(KeyError, mock) michael@0: self.assertEqual(mock.foo.bar(), 33) michael@0: self.assertIsInstance(mock.foo, MagicMock) michael@0: michael@0: michael@0: def test_patch_dict_keyword_args(self): michael@0: original = {'foo': 'bar'} michael@0: copy = original.copy() michael@0: michael@0: patcher = patch.dict(original, foo=3, bar=4, baz=5) michael@0: patcher.start() michael@0: michael@0: try: michael@0: self.assertEqual(original, dict(foo=3, bar=4, baz=5)) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: self.assertEqual(original, copy) michael@0: michael@0: michael@0: def test_autospec(self): michael@0: class Boo(object): michael@0: def __init__(self, a): michael@0: pass michael@0: def f(self, a): michael@0: pass michael@0: def g(self): michael@0: pass michael@0: foo = 'bar' michael@0: michael@0: class Bar(object): michael@0: def a(self): michael@0: pass michael@0: michael@0: def _test(mock): michael@0: mock(1) michael@0: mock.assert_called_with(1) michael@0: self.assertRaises(TypeError, mock) michael@0: michael@0: def _test2(mock): michael@0: mock.f(1) michael@0: mock.f.assert_called_with(1) michael@0: self.assertRaises(TypeError, mock.f) michael@0: michael@0: mock.g() michael@0: mock.g.assert_called_with() michael@0: self.assertRaises(TypeError, mock.g, 1) michael@0: michael@0: self.assertRaises(AttributeError, getattr, mock, 'h') michael@0: michael@0: mock.foo.lower() michael@0: mock.foo.lower.assert_called_with() michael@0: self.assertRaises(AttributeError, getattr, mock.foo, 'bar') michael@0: michael@0: mock.Bar() michael@0: mock.Bar.assert_called_with() michael@0: michael@0: mock.Bar.a() michael@0: mock.Bar.a.assert_called_with() michael@0: self.assertRaises(TypeError, mock.Bar.a, 1) michael@0: michael@0: mock.Bar().a() michael@0: mock.Bar().a.assert_called_with() michael@0: self.assertRaises(TypeError, mock.Bar().a, 1) michael@0: michael@0: self.assertRaises(AttributeError, getattr, mock.Bar, 'b') michael@0: self.assertRaises(AttributeError, getattr, mock.Bar(), 'b') michael@0: michael@0: def function(mock): michael@0: _test(mock) michael@0: _test2(mock) michael@0: _test2(mock(1)) michael@0: self.assertIs(mock, Foo) michael@0: return mock michael@0: michael@0: test = patch(foo_name, autospec=True)(function) michael@0: michael@0: mock = test() michael@0: self.assertIsNot(Foo, mock) michael@0: # test patching a second time works michael@0: test() michael@0: michael@0: module = sys.modules[__name__] michael@0: test = patch.object(module, 'Foo', autospec=True)(function) michael@0: michael@0: mock = test() michael@0: self.assertIsNot(Foo, mock) michael@0: # test patching a second time works michael@0: test() michael@0: michael@0: michael@0: def test_autospec_function(self): michael@0: @patch('%s.function' % __name__, autospec=True) michael@0: def test(mock): michael@0: function(1) michael@0: function.assert_called_with(1) michael@0: function(2, 3) michael@0: function.assert_called_with(2, 3) michael@0: michael@0: self.assertRaises(TypeError, function) michael@0: self.assertRaises(AttributeError, getattr, function, 'foo') michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_autospec_keywords(self): michael@0: @patch('%s.function' % __name__, autospec=True, michael@0: return_value=3) michael@0: def test(mock_function): michael@0: #self.assertEqual(function.abc, 'foo') michael@0: return function(1, 2) michael@0: michael@0: result = test() michael@0: self.assertEqual(result, 3) michael@0: michael@0: michael@0: def test_autospec_with_new(self): michael@0: patcher = patch('%s.function' % __name__, new=3, autospec=True) michael@0: self.assertRaises(TypeError, patcher.start) michael@0: michael@0: module = sys.modules[__name__] michael@0: patcher = patch.object(module, 'function', new=3, autospec=True) michael@0: self.assertRaises(TypeError, patcher.start) michael@0: michael@0: michael@0: def test_autospec_with_object(self): michael@0: class Bar(Foo): michael@0: extra = [] michael@0: michael@0: patcher = patch(foo_name, autospec=Bar) michael@0: mock = patcher.start() michael@0: try: michael@0: self.assertIsInstance(mock, Bar) michael@0: self.assertIsInstance(mock.extra, list) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_autospec_inherits(self): michael@0: FooClass = Foo michael@0: patcher = patch(foo_name, autospec=True) michael@0: mock = patcher.start() michael@0: try: michael@0: self.assertIsInstance(mock, FooClass) michael@0: self.assertIsInstance(mock(3), FooClass) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_autospec_name(self): michael@0: patcher = patch(foo_name, autospec=True) michael@0: mock = patcher.start() michael@0: michael@0: try: michael@0: self.assertIn(" name='Foo'", repr(mock)) michael@0: self.assertIn(" name='Foo.f'", repr(mock.f)) michael@0: self.assertIn(" name='Foo()'", repr(mock(None))) michael@0: self.assertIn(" name='Foo().f'", repr(mock(None).f)) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_tracebacks(self): michael@0: @patch.object(Foo, 'f', object()) michael@0: def test(): michael@0: raise AssertionError michael@0: try: michael@0: test() michael@0: except: michael@0: err = sys.exc_info() michael@0: michael@0: result = unittest2.TextTestResult(None, None, 0) michael@0: traceback = result._exc_info_to_string(err, self) michael@0: self.assertIn('raise AssertionError', traceback) michael@0: michael@0: michael@0: def test_new_callable_patch(self): michael@0: patcher = patch(foo_name, new_callable=NonCallableMagicMock) michael@0: michael@0: m1 = patcher.start() michael@0: patcher.stop() michael@0: m2 = patcher.start() michael@0: patcher.stop() michael@0: michael@0: self.assertIsNot(m1, m2) michael@0: for mock in m1, m2: michael@0: self.assertNotCallable(m1) michael@0: michael@0: michael@0: def test_new_callable_patch_object(self): michael@0: patcher = patch.object(Foo, 'f', new_callable=NonCallableMagicMock) michael@0: michael@0: m1 = patcher.start() michael@0: patcher.stop() michael@0: m2 = patcher.start() michael@0: patcher.stop() michael@0: michael@0: self.assertIsNot(m1, m2) michael@0: for mock in m1, m2: michael@0: self.assertNotCallable(m1) michael@0: michael@0: michael@0: def test_new_callable_keyword_arguments(self): michael@0: class Bar(object): michael@0: kwargs = None michael@0: def __init__(self, **kwargs): michael@0: Bar.kwargs = kwargs michael@0: michael@0: patcher = patch(foo_name, new_callable=Bar, arg1=1, arg2=2) michael@0: m = patcher.start() michael@0: try: michael@0: self.assertIs(type(m), Bar) michael@0: self.assertEqual(Bar.kwargs, dict(arg1=1, arg2=2)) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_new_callable_spec(self): michael@0: class Bar(object): michael@0: kwargs = None michael@0: def __init__(self, **kwargs): michael@0: Bar.kwargs = kwargs michael@0: michael@0: patcher = patch(foo_name, new_callable=Bar, spec=Bar) michael@0: patcher.start() michael@0: try: michael@0: self.assertEqual(Bar.kwargs, dict(spec=Bar)) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: patcher = patch(foo_name, new_callable=Bar, spec_set=Bar) michael@0: patcher.start() michael@0: try: michael@0: self.assertEqual(Bar.kwargs, dict(spec_set=Bar)) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_new_callable_create(self): michael@0: non_existent_attr = '%s.weeeee' % foo_name michael@0: p = patch(non_existent_attr, new_callable=NonCallableMock) michael@0: self.assertRaises(AttributeError, p.start) michael@0: michael@0: p = patch(non_existent_attr, new_callable=NonCallableMock, michael@0: create=True) michael@0: m = p.start() michael@0: try: michael@0: self.assertNotCallable(m, magic=False) michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_new_callable_incompatible_with_new(self): michael@0: self.assertRaises( michael@0: ValueError, patch, foo_name, new=object(), new_callable=MagicMock michael@0: ) michael@0: self.assertRaises( michael@0: ValueError, patch.object, Foo, 'f', new=object(), michael@0: new_callable=MagicMock michael@0: ) michael@0: michael@0: michael@0: def test_new_callable_incompatible_with_autospec(self): michael@0: self.assertRaises( michael@0: ValueError, patch, foo_name, new_callable=MagicMock, michael@0: autospec=True michael@0: ) michael@0: self.assertRaises( michael@0: ValueError, patch.object, Foo, 'f', new_callable=MagicMock, michael@0: autospec=True michael@0: ) michael@0: michael@0: michael@0: def test_new_callable_inherit_for_mocks(self): michael@0: class MockSub(Mock): michael@0: pass michael@0: michael@0: MockClasses = ( michael@0: NonCallableMock, NonCallableMagicMock, MagicMock, Mock, MockSub michael@0: ) michael@0: for Klass in MockClasses: michael@0: for arg in 'spec', 'spec_set': michael@0: kwargs = {arg: True} michael@0: p = patch(foo_name, new_callable=Klass, **kwargs) michael@0: m = p.start() michael@0: try: michael@0: instance = m.return_value michael@0: self.assertRaises(AttributeError, getattr, instance, 'x') michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_new_callable_inherit_non_mock(self): michael@0: class NotAMock(object): michael@0: def __init__(self, spec): michael@0: self.spec = spec michael@0: michael@0: p = patch(foo_name, new_callable=NotAMock, spec=True) michael@0: m = p.start() michael@0: try: michael@0: self.assertTrue(is_instance(m, NotAMock)) michael@0: self.assertRaises(AttributeError, getattr, m, 'return_value') michael@0: finally: michael@0: p.stop() michael@0: michael@0: self.assertEqual(m.spec, Foo) michael@0: michael@0: michael@0: def test_new_callable_class_decorating(self): michael@0: test = self michael@0: original = Foo michael@0: class SomeTest(object): michael@0: michael@0: def _test(self, mock_foo): michael@0: test.assertIsNot(Foo, original) michael@0: test.assertIs(Foo, mock_foo) michael@0: test.assertIsInstance(Foo, SomeClass) michael@0: michael@0: def test_two(self, mock_foo): michael@0: self._test(mock_foo) michael@0: def test_one(self, mock_foo): michael@0: self._test(mock_foo) michael@0: michael@0: SomeTest = patch(foo_name, new_callable=SomeClass)(SomeTest) michael@0: SomeTest().test_one() michael@0: SomeTest().test_two() michael@0: self.assertIs(Foo, original) michael@0: michael@0: michael@0: def test_patch_multiple(self): michael@0: original_foo = Foo michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: patcher1 = patch.multiple(foo_name, f=1, g=2) michael@0: patcher2 = patch.multiple(Foo, f=1, g=2) michael@0: michael@0: for patcher in patcher1, patcher2: michael@0: patcher.start() michael@0: try: michael@0: self.assertIs(Foo, original_foo) michael@0: self.assertEqual(Foo.f, 1) michael@0: self.assertEqual(Foo.g, 2) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: self.assertIs(Foo, original_foo) michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: @patch.multiple(foo_name, f=3, g=4) michael@0: def test(): michael@0: self.assertIs(Foo, original_foo) michael@0: self.assertEqual(Foo.f, 3) michael@0: self.assertEqual(Foo.g, 4) michael@0: michael@0: test() michael@0: michael@0: michael@0: def test_patch_multiple_no_kwargs(self): michael@0: self.assertRaises(ValueError, patch.multiple, foo_name) michael@0: self.assertRaises(ValueError, patch.multiple, Foo) michael@0: michael@0: michael@0: def test_patch_multiple_create_mocks(self): michael@0: original_foo = Foo michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: @patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT) michael@0: def test(f, foo): michael@0: self.assertIs(Foo, original_foo) michael@0: self.assertIs(Foo.f, f) michael@0: self.assertEqual(Foo.g, 3) michael@0: self.assertIs(Foo.foo, foo) michael@0: self.assertTrue(is_instance(f, MagicMock)) michael@0: self.assertTrue(is_instance(foo, MagicMock)) michael@0: michael@0: test() michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_patch_multiple_create_mocks_different_order(self): michael@0: # bug revealed by Jython! michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: patcher = patch.object(Foo, 'f', 3) michael@0: patcher.attribute_name = 'f' michael@0: michael@0: other = patch.object(Foo, 'g', DEFAULT) michael@0: other.attribute_name = 'g' michael@0: patcher.additional_patchers = [other] michael@0: michael@0: @patcher michael@0: def test(g): michael@0: self.assertIs(Foo.g, g) michael@0: self.assertEqual(Foo.f, 3) michael@0: michael@0: test() michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_patch_multiple_stacked_decorators(self): michael@0: original_foo = Foo michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: @patch.multiple(foo_name, f=DEFAULT) michael@0: @patch.multiple(foo_name, foo=DEFAULT) michael@0: @patch(foo_name + '.g') michael@0: def test1(g, **kwargs): michael@0: _test(g, **kwargs) michael@0: michael@0: @patch.multiple(foo_name, f=DEFAULT) michael@0: @patch(foo_name + '.g') michael@0: @patch.multiple(foo_name, foo=DEFAULT) michael@0: def test2(g, **kwargs): michael@0: _test(g, **kwargs) michael@0: michael@0: @patch(foo_name + '.g') michael@0: @patch.multiple(foo_name, f=DEFAULT) michael@0: @patch.multiple(foo_name, foo=DEFAULT) michael@0: def test3(g, **kwargs): michael@0: _test(g, **kwargs) michael@0: michael@0: def _test(g, **kwargs): michael@0: f = kwargs.pop('f') michael@0: foo = kwargs.pop('foo') michael@0: self.assertFalse(kwargs) michael@0: michael@0: self.assertIs(Foo, original_foo) michael@0: self.assertIs(Foo.f, f) michael@0: self.assertIs(Foo.g, g) michael@0: self.assertIs(Foo.foo, foo) michael@0: self.assertTrue(is_instance(f, MagicMock)) michael@0: self.assertTrue(is_instance(g, MagicMock)) michael@0: self.assertTrue(is_instance(foo, MagicMock)) michael@0: michael@0: test1() michael@0: test2() michael@0: test3() michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_patch_multiple_create_mocks_patcher(self): michael@0: original_foo = Foo michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: patcher = patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT) michael@0: michael@0: result = patcher.start() michael@0: try: michael@0: f = result['f'] michael@0: foo = result['foo'] michael@0: self.assertEqual(set(result), set(['f', 'foo'])) michael@0: michael@0: self.assertIs(Foo, original_foo) michael@0: self.assertIs(Foo.f, f) michael@0: self.assertIs(Foo.foo, foo) michael@0: self.assertTrue(is_instance(f, MagicMock)) michael@0: self.assertTrue(is_instance(foo, MagicMock)) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_patch_multiple_decorating_class(self): michael@0: test = self michael@0: original_foo = Foo michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: class SomeTest(object): michael@0: michael@0: def _test(self, f, foo): michael@0: test.assertIs(Foo, original_foo) michael@0: test.assertIs(Foo.f, f) michael@0: test.assertEqual(Foo.g, 3) michael@0: test.assertIs(Foo.foo, foo) michael@0: test.assertTrue(is_instance(f, MagicMock)) michael@0: test.assertTrue(is_instance(foo, MagicMock)) michael@0: michael@0: def test_two(self, f, foo): michael@0: self._test(f, foo) michael@0: def test_one(self, f, foo): michael@0: self._test(f, foo) michael@0: michael@0: SomeTest = patch.multiple( michael@0: foo_name, f=DEFAULT, g=3, foo=DEFAULT michael@0: )(SomeTest) michael@0: michael@0: thing = SomeTest() michael@0: thing.test_one() michael@0: thing.test_two() michael@0: michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_patch_multiple_create(self): michael@0: patcher = patch.multiple(Foo, blam='blam') michael@0: self.assertRaises(AttributeError, patcher.start) michael@0: michael@0: patcher = patch.multiple(Foo, blam='blam', create=True) michael@0: patcher.start() michael@0: try: michael@0: self.assertEqual(Foo.blam, 'blam') michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: self.assertFalse(hasattr(Foo, 'blam')) michael@0: michael@0: michael@0: def test_patch_multiple_spec_set(self): michael@0: # if spec_set works then we can assume that spec and autospec also michael@0: # work as the underlying machinery is the same michael@0: patcher = patch.multiple(Foo, foo=DEFAULT, spec_set=['a', 'b']) michael@0: result = patcher.start() michael@0: try: michael@0: self.assertEqual(Foo.foo, result['foo']) michael@0: Foo.foo.a(1) michael@0: Foo.foo.b(2) michael@0: Foo.foo.a.assert_called_with(1) michael@0: Foo.foo.b.assert_called_with(2) michael@0: self.assertRaises(AttributeError, setattr, Foo.foo, 'c', None) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_patch_multiple_new_callable(self): michael@0: class Thing(object): michael@0: pass michael@0: michael@0: patcher = patch.multiple( michael@0: Foo, f=DEFAULT, g=DEFAULT, new_callable=Thing michael@0: ) michael@0: result = patcher.start() michael@0: try: michael@0: self.assertIs(Foo.f, result['f']) michael@0: self.assertIs(Foo.g, result['g']) michael@0: self.assertIsInstance(Foo.f, Thing) michael@0: self.assertIsInstance(Foo.g, Thing) michael@0: self.assertIsNot(Foo.f, Foo.g) michael@0: finally: michael@0: patcher.stop() michael@0: michael@0: michael@0: def test_nested_patch_failure(self): michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: @patch.object(Foo, 'g', 1) michael@0: @patch.object(Foo, 'missing', 1) michael@0: @patch.object(Foo, 'f', 1) michael@0: def thing1(): michael@0: pass michael@0: michael@0: @patch.object(Foo, 'missing', 1) michael@0: @patch.object(Foo, 'g', 1) michael@0: @patch.object(Foo, 'f', 1) michael@0: def thing2(): michael@0: pass michael@0: michael@0: @patch.object(Foo, 'g', 1) michael@0: @patch.object(Foo, 'f', 1) michael@0: @patch.object(Foo, 'missing', 1) michael@0: def thing3(): michael@0: pass michael@0: michael@0: for func in thing1, thing2, thing3: michael@0: self.assertRaises(AttributeError, func) michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_new_callable_failure(self): michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: original_foo = Foo.foo michael@0: michael@0: def crasher(): michael@0: raise NameError('crasher') michael@0: michael@0: @patch.object(Foo, 'g', 1) michael@0: @patch.object(Foo, 'foo', new_callable=crasher) michael@0: @patch.object(Foo, 'f', 1) michael@0: def thing1(): michael@0: pass michael@0: michael@0: @patch.object(Foo, 'foo', new_callable=crasher) michael@0: @patch.object(Foo, 'g', 1) michael@0: @patch.object(Foo, 'f', 1) michael@0: def thing2(): michael@0: pass michael@0: michael@0: @patch.object(Foo, 'g', 1) michael@0: @patch.object(Foo, 'f', 1) michael@0: @patch.object(Foo, 'foo', new_callable=crasher) michael@0: def thing3(): michael@0: pass michael@0: michael@0: for func in thing1, thing2, thing3: michael@0: self.assertRaises(NameError, func) michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: self.assertEqual(Foo.foo, original_foo) michael@0: michael@0: michael@0: def test_patch_multiple_failure(self): michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: michael@0: patcher = patch.object(Foo, 'f', 1) michael@0: patcher.attribute_name = 'f' michael@0: michael@0: good = patch.object(Foo, 'g', 1) michael@0: good.attribute_name = 'g' michael@0: michael@0: bad = patch.object(Foo, 'missing', 1) michael@0: bad.attribute_name = 'missing' michael@0: michael@0: for additionals in [good, bad], [bad, good]: michael@0: patcher.additional_patchers = additionals michael@0: michael@0: @patcher michael@0: def func(): michael@0: pass michael@0: michael@0: self.assertRaises(AttributeError, func) michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: michael@0: michael@0: def test_patch_multiple_new_callable_failure(self): michael@0: original_f = Foo.f michael@0: original_g = Foo.g michael@0: original_foo = Foo.foo michael@0: michael@0: def crasher(): michael@0: raise NameError('crasher') michael@0: michael@0: patcher = patch.object(Foo, 'f', 1) michael@0: patcher.attribute_name = 'f' michael@0: michael@0: good = patch.object(Foo, 'g', 1) michael@0: good.attribute_name = 'g' michael@0: michael@0: bad = patch.object(Foo, 'foo', new_callable=crasher) michael@0: bad.attribute_name = 'foo' michael@0: michael@0: for additionals in [good, bad], [bad, good]: michael@0: patcher.additional_patchers = additionals michael@0: michael@0: @patcher michael@0: def func(): michael@0: pass michael@0: michael@0: self.assertRaises(NameError, func) michael@0: self.assertEqual(Foo.f, original_f) michael@0: self.assertEqual(Foo.g, original_g) michael@0: self.assertEqual(Foo.foo, original_foo) michael@0: michael@0: michael@0: def test_patch_multiple_string_subclasses(self): michael@0: for base in (str, unicode): michael@0: Foo = type('Foo', (base,), {'fish': 'tasty'}) michael@0: foo = Foo() michael@0: @patch.multiple(foo, fish='nearly gone') michael@0: def test(): michael@0: self.assertEqual(foo.fish, 'nearly gone') michael@0: michael@0: test() michael@0: self.assertEqual(foo.fish, 'tasty') michael@0: michael@0: michael@0: @patch('mock.patch.TEST_PREFIX', 'foo') michael@0: def test_patch_test_prefix(self): michael@0: class Foo(object): michael@0: thing = 'original' michael@0: michael@0: def foo_one(self): michael@0: return self.thing michael@0: def foo_two(self): michael@0: return self.thing michael@0: def test_one(self): michael@0: return self.thing michael@0: def test_two(self): michael@0: return self.thing michael@0: michael@0: Foo = patch.object(Foo, 'thing', 'changed')(Foo) michael@0: michael@0: foo = Foo() michael@0: self.assertEqual(foo.foo_one(), 'changed') michael@0: self.assertEqual(foo.foo_two(), 'changed') michael@0: self.assertEqual(foo.test_one(), 'original') michael@0: self.assertEqual(foo.test_two(), 'original') michael@0: michael@0: michael@0: @patch('mock.patch.TEST_PREFIX', 'bar') michael@0: def test_patch_dict_test_prefix(self): michael@0: class Foo(object): michael@0: def bar_one(self): michael@0: return dict(the_dict) michael@0: def bar_two(self): michael@0: return dict(the_dict) michael@0: def test_one(self): michael@0: return dict(the_dict) michael@0: def test_two(self): michael@0: return dict(the_dict) michael@0: michael@0: the_dict = {'key': 'original'} michael@0: Foo = patch.dict(the_dict, key='changed')(Foo) michael@0: michael@0: foo =Foo() michael@0: self.assertEqual(foo.bar_one(), {'key': 'changed'}) michael@0: self.assertEqual(foo.bar_two(), {'key': 'changed'}) michael@0: self.assertEqual(foo.test_one(), {'key': 'original'}) michael@0: self.assertEqual(foo.test_two(), {'key': 'original'}) michael@0: michael@0: michael@0: def test_patch_with_spec_mock_repr(self): michael@0: for arg in ('spec', 'autospec', 'spec_set'): michael@0: p = patch('%s.SomeClass' % __name__, **{arg: True}) michael@0: m = p.start() michael@0: try: michael@0: self.assertIn(" name='SomeClass'", repr(m)) michael@0: self.assertIn(" name='SomeClass.class_attribute'", michael@0: repr(m.class_attribute)) michael@0: self.assertIn(" name='SomeClass()'", repr(m())) michael@0: self.assertIn(" name='SomeClass().class_attribute'", michael@0: repr(m().class_attribute)) michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_patch_nested_autospec_repr(self): michael@0: p = patch('tests.support', autospec=True) michael@0: m = p.start() michael@0: try: michael@0: self.assertIn(" name='support.SomeClass.wibble()'", michael@0: repr(m.SomeClass.wibble())) michael@0: self.assertIn(" name='support.SomeClass().wibble()'", michael@0: repr(m.SomeClass().wibble())) michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_mock_calls_with_patch(self): michael@0: for arg in ('spec', 'autospec', 'spec_set'): michael@0: p = patch('%s.SomeClass' % __name__, **{arg: True}) michael@0: m = p.start() michael@0: try: michael@0: m.wibble() michael@0: michael@0: kalls = [call.wibble()] michael@0: self.assertEqual(m.mock_calls, kalls) michael@0: self.assertEqual(m.method_calls, kalls) michael@0: self.assertEqual(m.wibble.mock_calls, [call()]) michael@0: michael@0: result = m() michael@0: kalls.append(call()) michael@0: self.assertEqual(m.mock_calls, kalls) michael@0: michael@0: result.wibble() michael@0: kalls.append(call().wibble()) michael@0: self.assertEqual(m.mock_calls, kalls) michael@0: michael@0: self.assertEqual(result.mock_calls, [call.wibble()]) michael@0: self.assertEqual(result.wibble.mock_calls, [call()]) michael@0: self.assertEqual(result.method_calls, [call.wibble()]) michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_patch_imports_lazily(self): michael@0: sys.modules.pop('squizz', None) michael@0: michael@0: p1 = patch('squizz.squozz') michael@0: self.assertRaises(ImportError, p1.start) michael@0: michael@0: squizz = Mock() michael@0: squizz.squozz = 6 michael@0: sys.modules['squizz'] = squizz michael@0: p1 = patch('squizz.squozz') michael@0: squizz.squozz = 3 michael@0: p1.start() michael@0: p1.stop() michael@0: self.assertEqual(squizz.squozz, 3) michael@0: michael@0: michael@0: def test_patch_propogrates_exc_on_exit(self): michael@0: class holder: michael@0: exc_info = None, None, None michael@0: michael@0: class custom_patch(_patch): michael@0: def __exit__(self, etype=None, val=None, tb=None): michael@0: _patch.__exit__(self, etype, val, tb) michael@0: holder.exc_info = etype, val, tb michael@0: stop = __exit__ michael@0: michael@0: def with_custom_patch(target): michael@0: getter, attribute = _get_target(target) michael@0: return custom_patch( michael@0: getter, attribute, DEFAULT, None, False, None, michael@0: None, None, {} michael@0: ) michael@0: michael@0: @with_custom_patch('squizz.squozz') michael@0: def test(mock): michael@0: raise RuntimeError michael@0: michael@0: self.assertRaises(RuntimeError, test) michael@0: self.assertIs(holder.exc_info[0], RuntimeError) michael@0: self.assertIsNotNone(holder.exc_info[1], michael@0: 'exception value not propgated') michael@0: self.assertIsNotNone(holder.exc_info[2], michael@0: 'exception traceback not propgated') michael@0: michael@0: michael@0: def test_create_and_specs(self): michael@0: for kwarg in ('spec', 'spec_set', 'autospec'): michael@0: p = patch('%s.doesnotexist' % __name__, create=True, michael@0: **{kwarg: True}) michael@0: self.assertRaises(TypeError, p.start) michael@0: self.assertRaises(NameError, lambda: doesnotexist) michael@0: michael@0: # check that spec with create is innocuous if the original exists michael@0: p = patch(MODNAME, create=True, **{kwarg: True}) michael@0: p.start() michael@0: p.stop() michael@0: michael@0: michael@0: def test_multiple_specs(self): michael@0: original = PTModule michael@0: for kwarg in ('spec', 'spec_set'): michael@0: p = patch(MODNAME, autospec=0, **{kwarg: 0}) michael@0: self.assertRaises(TypeError, p.start) michael@0: self.assertIs(PTModule, original) michael@0: michael@0: for kwarg in ('spec', 'autospec'): michael@0: p = patch(MODNAME, spec_set=0, **{kwarg: 0}) michael@0: self.assertRaises(TypeError, p.start) michael@0: self.assertIs(PTModule, original) michael@0: michael@0: for kwarg in ('spec_set', 'autospec'): michael@0: p = patch(MODNAME, spec=0, **{kwarg: 0}) michael@0: self.assertRaises(TypeError, p.start) michael@0: self.assertIs(PTModule, original) michael@0: michael@0: michael@0: def test_specs_false_instead_of_none(self): michael@0: p = patch(MODNAME, spec=False, spec_set=False, autospec=False) michael@0: mock = p.start() michael@0: try: michael@0: # no spec should have been set, so attribute access should not fail michael@0: mock.does_not_exist michael@0: mock.does_not_exist = 3 michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_falsey_spec(self): michael@0: for kwarg in ('spec', 'autospec', 'spec_set'): michael@0: p = patch(MODNAME, **{kwarg: 0}) michael@0: m = p.start() michael@0: try: michael@0: self.assertRaises(AttributeError, getattr, m, 'doesnotexit') michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_spec_set_true(self): michael@0: for kwarg in ('spec', 'autospec'): michael@0: p = patch(MODNAME, spec_set=True, **{kwarg: True}) michael@0: m = p.start() michael@0: try: michael@0: self.assertRaises(AttributeError, setattr, m, michael@0: 'doesnotexist', 'something') michael@0: self.assertRaises(AttributeError, getattr, m, 'doesnotexist') michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_callable_spec_as_list(self): michael@0: spec = ('__call__',) michael@0: p = patch(MODNAME, spec=spec) michael@0: m = p.start() michael@0: try: michael@0: self.assertTrue(callable(m)) michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_not_callable_spec_as_list(self): michael@0: spec = ('foo', 'bar') michael@0: p = patch(MODNAME, spec=spec) michael@0: m = p.start() michael@0: try: michael@0: self.assertFalse(callable(m)) michael@0: finally: michael@0: p.stop() michael@0: michael@0: michael@0: def test_patch_stopall(self): michael@0: unlink = os.unlink michael@0: chdir = os.chdir michael@0: path = os.path michael@0: patch('os.unlink', something).start() michael@0: patch('os.chdir', something_else).start() michael@0: michael@0: @patch('os.path') michael@0: def patched(mock_path): michael@0: patch.stopall() michael@0: self.assertIs(os.path, mock_path) michael@0: self.assertIs(os.unlink, unlink) michael@0: self.assertIs(os.chdir, chdir) michael@0: michael@0: patched() michael@0: self.assertIs(os.path, path) michael@0: michael@0: michael@0: michael@0: if __name__ == '__main__': michael@0: unittest2.main()