Search code examples
pythonunit-testingtestingmockingpython-unittest

Patch over a function imported inside another function


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?


Solution

  • 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')