用于函数的 Python unittest.mock.patch 不起作用

Lar*_*iat 2 python django unit-testing mocking

我正在尝试使用带有 mock.patch 的单元测试来测试我的 python 应用程序,但它不起作用。我的代码:

测试文件.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')
Run Code Online (Sandbox Code Playgroud)

发布请求调用检查“用户身份验证”使用get_authenticated_user功能的装饰器。但是在装饰器中,我得到了函数而不是模拟对象。

装饰器.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'}
Run Code Online (Sandbox Code Playgroud)

为什么decorators.py我得到了一个函数而不是模拟对象?Python 版本是 3.4.0

Mar*_*ers 6

您似乎正在修补错误的位置。在decorators.py您使用的是全球性的名字get_authenticated_user(),但你在修补的名称api.accounts.helpers来代替。

您可能导入get_authenticated_user了:

from api.accounts.helpers import get_authenticated_user
Run Code Online (Sandbox Code Playgroud)

这意味着修补原始位置不会改变在参考decorators

修补全局decorators

@patch('decorators.get_authenticated_user', return_value={'username': 'username'})
Run Code Online (Sandbox Code Playgroud)

还看到哪里修补部分的的mock文档:

patch()通过(临时)将名称指向的对象更改为另一个对象。可以有许多名称指向任何单个对象,因此要使修补工作,您必须确保修补被测系统使用的名称。

基本原则是在查找对象的位置打补丁,该位置不一定与定义它的位置相同。