Python mock global function that is used in class

mockingpythonunit testing

I can't seem to get my head around mocking in Python. I have a global function:

a.py:

def has_permission(args):
    ret_val = ...get-true-or-false...
    return ret_val

b.py:

class MySerializer(HyperlinkedModelSerializer):

     def get_fields():
         fields = super().get_fields()
         for f in :
             if has_permission(...):
                 ret_val[f.name] = fields[f]
         return ret_val

c.py:

class CountrySerializer(MySerializer):
    class Meta:
        model = Country

Question: Now i want to test c.py, but i want to mock the has_permission function that is defined in a.py, but is called in the get_fields-method of the class MySerializer that is defined in b.py … How do i do that?

I've tried things like:

@patch('b.MySerializer.has_permission')

and

@patch('b.MySerializer.get_fields.has_permission')

and

@patch('a.has_permission')

But everything i try either just doesn't work and has_permission is still executed, or python complains about that it can't find the attribute 'has_permission'

with the patching done in:

test.py

class TestSerializerFields(TestCase):
    @patch(... the above examples....)
    def test_my_country_serializer():
        s = CountrySerializer()
        self..assertTrue(issubclass(my_serializer_fields.MyCharField, type(s.get_fields()['field1'])))

Best Answer

You need to patch the global in the b module:

@patch('b.has_permission')

because that's where your code looks for it.

Also see the Where to patch section of the mock documentation.

Related Topic