summaryrefslogtreecommitdiff
path: root/oslotest/tests/unit/test_mock_fixture.py
diff options
context:
space:
mode:
Diffstat (limited to 'oslotest/tests/unit/test_mock_fixture.py')
-rw-r--r--oslotest/tests/unit/test_mock_fixture.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/oslotest/tests/unit/test_mock_fixture.py b/oslotest/tests/unit/test_mock_fixture.py
new file mode 100644
index 0000000..a574e08
--- /dev/null
+++ b/oslotest/tests/unit/test_mock_fixture.py
@@ -0,0 +1,104 @@
+# Copyright 2017 Cloudbase Solutions Srl
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import mock
+import testtools
+
+from oslotest import mock_fixture
+
+# NOTE(claudiub): this needs to be called before any mock.patch calls are
+# being done, and especially before the test class loads. This fixes
+# the mock.patch autospec issue:
+# https://github.com/testing-cabal/mock/issues/396
+# TODO(claudiub): Remove this once the fix has been merged and released.
+mock_fixture.patch_mock_module()
+
+
+class Foo(object):
+ def bar(self, a, b, c, d=None):
+ pass
+
+ @classmethod
+ def classic_bar(cls, a, b, c, d=None):
+ pass
+
+ @staticmethod
+ def static_bar(a, b, c, d=None):
+ pass
+
+
+class MockSanityTestCase(testtools.TestCase):
+
+ def setUp(self):
+ super(MockSanityTestCase, self).setUp()
+ self.useFixture(mock_fixture.MockAutospecFixture())
+
+ def _check_autospeced_foo(self, foo):
+ for method_name in ['bar', 'classic_bar', 'static_bar']:
+ mock_method = getattr(foo, method_name)
+
+ # check that the methods are callable with correct args.
+ mock_method(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c)
+ mock_method(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c,
+ d=mock.sentinel.d)
+ mock_method.assert_has_calls([
+ mock.call(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c),
+ mock.call(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c,
+ d=mock.sentinel.d)])
+
+ # assert that TypeError is raised if the method signature is not
+ # respected.
+ self.assertRaises(TypeError, mock_method)
+ self.assertRaises(TypeError, mock_method, mock.sentinel.a)
+ self.assertRaises(TypeError, mock_method, a=mock.sentinel.a)
+ self.assertRaises(TypeError, mock_method, mock.sentinel.a,
+ mock.sentinel.b, mock.sentinel.c,
+ e=mock.sentinel.e)
+
+ # assert that AttributeError is raised if the method does not exist.
+ self.assertRaises(AttributeError, getattr, foo, 'lish')
+
+ def test_mock_autospec_all_members(self):
+ for spec in [Foo, Foo()]:
+ foo = mock.Mock(autospec=spec)
+ self._check_autospeced_foo(foo)
+
+ @mock.patch.object(Foo, 'static_bar')
+ @mock.patch.object(Foo, 'classic_bar')
+ @mock.patch.object(Foo, 'bar')
+ def test_patch_autospec_class(self, mock_meth, mock_cmeth, mock_smeth):
+ foo = Foo()
+ self._check_autospeced_foo(foo)
+
+ @mock.patch.object(Foo, 'static_bar', autospec=False)
+ @mock.patch.object(Foo, 'classic_bar', autospec=False)
+ @mock.patch.object(Foo, 'bar', autospec=False)
+ def test_patch_autospec_class_false(self, mock_meth, mock_cmeth,
+ mock_smeth):
+ foo = Foo()
+ # we're checking that method signature is not enforced.
+ foo.bar()
+ mock_meth.assert_called_once_with()
+ foo.classic_bar()
+ mock_cmeth.assert_called_once_with()
+ foo.static_bar()
+ mock_smeth.assert_called_once_with()
+
+ @mock.patch.object(Foo, 'lish', create=True)
+ def test_patch_create(self, mock_lish):
+ foo = Foo()
+
+ foo.lish()
+ mock_lish.assert_called_once_with()