Bobby Battista
Bobby Battista

Reputation: 2075

Mocking a function in another file and a class in a second other file

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?

Upvotes: 1

Views: 8562

Answers (2)

Bobby Battista
Bobby Battista

Reputation: 2075

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.

Upvotes: 2

garyboland
garyboland

Reputation: 135

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

Upvotes: 0

Related Questions