Patch over a function imported inside another function

Wilduck picture Wilduck · Mar 5, 2014 · Viewed 12k times · Source

In order to avoid a circular import, I've been forced to define a function that looks like:

# do_something.py

def do_it():
    from .helpers import do_it_helper
    # do stuff

Now I'd like to be able to test this function, with do_it_helper patched over. If the import were a top level import,

class Test_do_it(unittest.TestCase):
    def test_do_it(self):
        with patch('do_something.do_it_helper') as helper_mock:
            helper_mock.return_value = 12
            # test things

would work fine. However, the code above gives me:

AttributeError: <module 'do_something'> does not have the attribute 'do_it_helper'

On a whim, I also tried changing the patch statement to:

with patch('do_something.do_it.do_it_helper') as helper_mock:

But that produced a similar error. Is there any way to mock this function, given the fact that I'm forced into importing it within the function where it's used?

Answer

alecxe picture alecxe · Mar 5, 2014

You should mock out helpers.do_it_helper:

class Test_do_it(unittest.TestCase):
    def test_do_it(self):
        with patch('helpers.do_it_helper') as helper_mock:
            helper_mock.return_value = 12
            # test things

Here's an example using mock on os.getcwd():

import unittest
from mock import patch


def get_cwd():
    from os import getcwd
    return getcwd()


class MyTestCase(unittest.TestCase):
    @patch('os.getcwd')
    def test_mocked(self, mock_function):
        mock_function.return_value = 'test'
        self.assertEqual(get_cwd(), 'test')

Hope that helps.