How to mock using patch relative paths?

Building on the accepted answer, I believe that this is the cleanest way to achieve desired goal:

from mock import patch
from .. import monkey

@patch(monkey.__name__+'.ook', Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(monkey.ook())
    mock_ook.run.assert_called_once_with('')

From what I gather, with mock, you need to provide a dotted name when patching. Luckily, every module has access to a special module-level variable __name__ which contains the module's name. Using this, if you want to patch variables local to your module, you should be able to do something like the following:

import mock
import unittest

ook = lambda: "the ook"


class OokTest(unittest.TestCase):

    def test_ook(self):
        with mock.patch(__name__ + '.ook', return_value=None):
            self.assertIsNone(ook())
        self.assertEquals(ook(), "the ook")

    # the patch decorator should work the same way, I just tend to use the
    # context manager out of personal preference
    @mock.patch(__name__ + '.ook', return_value=None)
    def test_ook_2(self, mock_ook):
        self.assertIsNone(ook())

Assuming you've saved that file as quicktest.py, the unit tests give this result:

$ python -m unittest quicktest
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

And of course, from a.b import c gives you a plain variable c in your package, so this same mechanism should work.


Not sure if this is the best way (or even recommended), but one way is to use something like:

from mock import patch,
from ..monkey import ook
[...]

package_base = __package__.rsplit('.', 1)[0]

@patch('{0}.monkey.ook'.format(package_base), Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(ook())
    mock_ook.run.assert_called_once_with('')

I used Dan Passaro's solution till I came across this one using patch.object – which looks even better to me:

from unittest.mock import patch,
from .. import monkey
[...]
@patch.object(monkey, 'ook', Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(monkey.ook())
    mock_ook.run.assert_called_once_with('')

Advantages:

  • No need for the boilerplate code that is __name__ + '.object_to_be_mocked'
  • All dependencies of the test case are clearly stated at the beginning of the file as import statements.
  • In cases where the dotted name of the object you're trying to mock out is longer (say "amazon.jungle.monkey.ook") and you therefore write @patch.object(amazon.jungle.monkey, 'ook', …), your IDE's static code analysis can make sure that at least amazon.jungle.monkey is a valid variable since you didn't write the whole thing as a string 'amazon.jungle.monkey.ook'.

Disadvantages:

  • You cannot do from ..monkey import ook but need to do from .. import monkey and access ook through monkey, i.e. monkey.ook. In cases where I need to write this often I will add ook = monkey.ook to the beginning of my tests for convenience. (Or even to the import statements in case I never need to mock out this particular property of monkey.)