1

I'm noticing that the class methods are being mocked out properly, but the function is bypassing the mock and running the actual function.

from module1 import myClass
from module2 import my_function
import unittest
from mock import patch

class TestStuff(unittest.TestCase):
    @patch('module2.my_function')
    @patch('module1.myClass.my_method')
    def test_my_function(self, mock_method, mock_function):
        test_obj = myClass()
        test_obj.my_method()
        assert mock_method.called
        my_function()
        assert mock_function.called

if I print out my_function() and type(my_function) it will not show the mock, but the real function. Does it matter that I'm importing a class then mocking a method, but I'm importing the function directly?

Bobby Battista
  • 1,985
  • 2
  • 17
  • 27
  • what does `my_function` look like? – ham_string Nov 09 '15 at 23:05
  • My function queries a database and returns a list of objects. I'd like to mock it out to avoid reads/writes to the db. The class method makes an API call to a third party, so I'd like to mock that out too. – Bobby Battista Nov 09 '15 at 23:27

2 Answers2

1

I think I found the issue: When I'm testing a function, and there's something I want to mock, I should not import it. Importing it causes it to get used, even if I've put the patch decorator. I think this was general confusion about how mocking/testing works. What I wanted to do was to test a function without actually querying the database. Instead of mocking out the whole function, I could take the line that actually hits the db - query.all() - and make it it's own function, then mock that out.

from module1 import myClass
from module2 import my_function

import unittest
from mock import patch

class TestStuff(unittest.TestCase):
    @patch('module2.db_query')
    @patch('module1.myClass.my_method')
    def test_my_function(self, mock_method, mock_db_query):
        test_obj = myClass()
        test_obj.my_method()
        assert mock_method.called
        my_function()  # my_function calls db_query(), now mocked out
        assert mock_db_query.called

If I had wanted to actually mock out the all of my_function, I could have just not imported it. At least that's how I'm understanding this at the moment.

Bobby Battista
  • 1,985
  • 2
  • 17
  • 27
  • 2
    I don't see any difference between question code and answer code except you changed text `my_function` to `db_query` – Jasmeet Jul 02 '19 at 22:44
0

I ran into a similar issue. Turns out I needed to give it the FULL path to my_function:

@patch('home.myuser.myprojects.mymodule.myfunc')

garyboland
  • 135
  • 12