2016-10-30 91 views
1

我试图测试我的python应用程序使用unitkit与mock.patch,但它不工作。 我的代码:python unittest.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请求调用勾选 “用户身份验证” 使用get_authenticated_user功能的装饰。但在装饰器中,我得到了函数,而不是模拟对象。

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我有一个函数,而不是模拟对象? Python版本是3.4.0

回答

3

您似乎在修补错误的位置。在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()作品(暂时)改变对象的名称指向与另一之一。可以有许多名称指向任何单个对象,因此为了修补工作,您必须确保您修补被测系统使用的名称。

基本原理是你修补对象的位置抬头,它不一定与它定义的位置相同。

+0

在他们的测试方法中'输入api.accounts.helpers as he'也似乎有点奇怪。当然,这并不是指出正确的修补位置,但是一直以来,它不会引起问题吗? – idjaw

+1

@idjaw:这只是试图验证补丁是否到位的OP。这是修补错误的参考,但是。如果他们尝试过'输入装饰器'和'decorators.get_authenticated_user',他们会发现该引用没有被修补。 –

+0

^^是的。这就是我想说的。谢谢。 – idjaw