简体   繁体   中英

Python unittest.mock.patch for function don't work

I'm trying to test my python application use unittests with mock.patch but it don't work as well. My code:

test_file.py

from unittest.mock import patch

class TestMaterialsUpdate(TestCase):
    def setUp(self):
        self.client = Client()

    @patch('api.accounts.helpers.get_authenticated_user', return_value={'username': 'username'})
    def test_my_castom_method(self):
       import api.accounts.helpers as he
       print(he.get_authenticated_user) # printed mock here
       print(he.get_authenticated_user) # returned {'username': 'username'}

       url = reverse('materials_create')
       # next call get_authenticated_user will be in post request
       self.client.post(url,data=json.dumps({'data': 'data'}), content_type='application/json')

The post request call the decorator that check "user auth" use get_authenticated_user function. But in decorator I got function instead mock-object.

decorators.py

def login_required(func):
    def wrapper(*args, **kwargs):
        print(get_authenticated_user) # printed <function get_authenticated_user at 0x7fec34b62510>
        user = get_authenticated_user(request) # return None instead {'username: 'username'}

Why in decorators.py I got a function instead the mock-object? Python version is 3.4.0

You appear to be patching the wrong location. In decorators.py you are using a global name get_authenticated_user() , but you are patching a name in api.accounts.helpers instead.

You probably imported get_authenticated_user with:

from api.accounts.helpers import get_authenticated_user

which means that patching the original location won't change the reference in decorators .

Patch the global in decorators :

@patch('decorators.get_authenticated_user', return_value={'username': 'username'})

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

patch() works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.

The basic principle is that you patch where an object is looked up , which is not necessarily the same place as where it is defined.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM