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

时间:2016-10-30 12:48:01

标签: python django unit-testing mocking

我试图测试我的python应用程序使用mock.patch的单元测试,但它也不起作用。 我的代码:

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

post请求调用查看" user auth"使用get_authenticated_user函数。但是在装饰器中我得到了函数而不是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'}

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

1 个答案:

答案 0 :(得分:4)

您似乎正在修补错误的位置。在decorators.py中,您使用的是全局名称get_authenticated_user(),但您正在修改api.accounts.helpers中的名称。

您可能导入了get_authenticated_user

from api.accounts.helpers import get_authenticated_user

这意味着修补原始位置不会改变 decorators 中的引用。

decorators

中修补全局
@patch('decorators.get_authenticated_user', return_value={'username': 'username'})

另请参阅mock文档的Where to patch section

  

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

     

基本原则是您在查找对象的位置进行修补,这不一定与定义对象的位置相同。