Add 'new' parameter to mock.Patch and mock.PatchObject classes

These two classes are using mock module, although both of them weren't using the
'new' parameter from mock.patch and mock.patch.object which allow us to set a
specific method to be executed instead of the using MagicMock.

As mock's patch doc string says (and it says in patch,object that the parameters
are the same):
"If `new` is omitted, then the target is replaced with a 'MagicMock'."

Unit test to prove that both approaches work were also added.

Usage example:
https://review.openstack.org/#/c/68140/2/tempest/tests/test_rest_client.py

I replaced request method from tempest's rest_client by a fake request which
gives a fake response to authentication request (Line 192 for instance).

Change-Id: I32a90b4d47174b6adb53b525a4add7002411b29d
This commit is contained in:
Mauro S. M. Rodrigues 2014-01-13 15:30:40 +00:00 committed by Gerrit Code Review
parent ece684a84d
commit b8a191b083
2 changed files with 59 additions and 4 deletions

View File

@ -22,14 +22,15 @@ import mock
class PatchObject(fixtures.Fixture):
"""Deal with code around mock."""
def __init__(self, obj, attr, **kwargs):
def __init__(self, obj, attr, new=mock.DEFAULT, **kwargs):
self.obj = obj
self.attr = attr
self.kwargs = kwargs
self.new = new
def setUp(self):
super(PatchObject, self).setUp()
_p = mock.patch.object(self.obj, self.attr, **self.kwargs)
_p = mock.patch.object(self.obj, self.attr, self.new, **self.kwargs)
self.mock = _p.start()
self.addCleanup(_p.stop)
@ -38,12 +39,13 @@ class Patch(fixtures.Fixture):
"""Deal with code around mock.patch."""
def __init__(self, obj, **kwargs):
def __init__(self, obj, new=mock.DEFAULT, **kwargs):
self.obj = obj
self.kwargs = kwargs
self.new = new
def setUp(self):
super(Patch, self).setUp()
_p = mock.patch(self.obj, **self.kwargs)
_p = mock.patch(self.obj, self.new, **self.kwargs)
self.mock = _p.start()
self.addCleanup(_p.stop)

View File

@ -0,0 +1,53 @@
# Copyright 2014 IBM Corp.
#
# 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
from openstack.common.fixture import mockpatch
from tests import utils
class Foo(object):
def bar(self):
pass
def mocking_bar(self):
return 'mocked!'
class TestMockPatch(utils.BaseTestCase):
def test_mock_patch_with_replacement(self):
self.useFixture(mockpatch.Patch('%s.Foo.bar' % (__name__),
mocking_bar))
instance = Foo()
self.assertEqual(instance.bar(), 'mocked!')
def test_mock_patch_without_replacement(self):
self.useFixture(mockpatch.Patch('%s.Foo.bar' % (__name__)))
instance = Foo()
self.assertIsInstance(instance.bar(), mock.MagicMock)
class TestMockPatchObject(utils.BaseTestCase):
def test_mock_patch_object_with_replacement(self):
self.useFixture(mockpatch.PatchObject(Foo, 'bar', mocking_bar))
instance = Foo()
self.assertEqual(instance.bar(), 'mocked!')
def test_mock_patch_object_without_replacement(self):
self.useFixture(mockpatch.PatchObject(Foo, 'bar'))
instance = Foo()
self.assertIsInstance(instance.bar(), mock.MagicMock)