diff options
Diffstat (limited to 'oslotest/tests/unit/test_mock_fixture.py')
-rw-r--r-- | oslotest/tests/unit/test_mock_fixture.py | 104 |
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() |