Search code examples
pythonunit-testingpython-unittestpython-mock

Python Mocking a function from an imported module


I want to understand how to @patch a function from an imported module.

This is where I am so far.

app/mocking.py:

from app.my_module import get_user_name

def test_method():
  return get_user_name()

if __name__ == "__main__":
  print "Starting Program..."
  test_method()

app/my_module/__init__.py:

def get_user_name():
  return "Unmocked User"

test/mock-test.py:

import unittest
from app.mocking import test_method 

def mock_get_user():
  return "Mocked This Silly"

@patch('app.my_module.get_user_name')
class MockingTestTestCase(unittest.TestCase):

  def test_mock_stubs(self, mock_method):
    mock_method.return_value = 'Mocked This Silly')
    ret = test_method()
    self.assertEqual(ret, 'Mocked This Silly')

if __name__ == '__main__':
  unittest.main()

This does not work as I would expect. The "patched" module simply returns the unmocked value of get_user_name. How do I mock methods from other packages that I am importing into a namespace under test?


Solution

  • When you are using the patch decorator from the unittest.mock package you are patching it in the namespace that is under test (in this case app.mocking.get_user_name), not the namespace the function is imported from (in this case app.my_module.get_user_name).

    To do what you describe with @patch try something like the below:

    from mock import patch
    from app.mocking import test_method 
    
    class MockingTestTestCase(unittest.TestCase):
        
        @patch('app.mocking.get_user_name')
        def test_mock_stubs(self, test_patch):
            test_patch.return_value = 'Mocked This Silly'
            ret = test_method()
            self.assertEqual(ret, 'Mocked This Silly')
    

    The standard library documentation includes a useful section describing this.