可以在Django测试中避免使用permission_required装饰器吗?
我正在测试一组Django应用程序,这些应用程序大量使用了'permission_required'这个装饰器。这个装饰器会导致我大多数视图返回一个302的HTTP响应。
我想问的是:有没有办法在测试时避免或关闭'permission_required',这样我调用我的视图时就能得到200的响应,而不是302?
谢谢!
3 个回答
0
好的。我找到的解决办法是在TestCase类的setUp方法里创建一个超级用户。我是这样做的:
def setUp(self):
self.client = Client()
self.user = User.objects.create_superuser(
'testuser',
'test@example.com',
'easy_password',
)
然后,当我想测试一个网址时,我这样做:
def test_search_customers(self):
url = reverse('customer_search')
response = self.client.get(url)
# Not logged user. Must return a 302 HTTP code.
self.assertEquals(response.status_code, 302)
self.assertEquals(response['Location'], 'http://testserver/unauthorized/?next=/search/customers/')
# HERE I LOG IN MY SUPERUSER
self.client.login(username='testuser', password='easy_password')
response = self.client.get(url, follow=True)
# Same URL requested with a logged user with permissions. Must return 200 HTTP code.
self.assertEquals(response.status_code, 200)
这对我来说有效 :)
谢谢大家。祝好,
何塞
1
你可以用一种叫“猴子补丁”的方法来解决这个问题:
import django.contrib.auth.decorators
real_permission_required = decorators.permission_required
# return a function that returns the exact function that was decorated, ignoring arguments
decorators.permission_required = lambda *args, **kwargs: lambda func: func
你需要确保这个操作在使用之前完成,也就是在它所装饰的对象被定义的时候。(比如,当这个模块被引入的时候。)
而且,这个操作必须在它被绑定到其他作用域之前完成。比如在 import django.contrib.auth.decorators
之后是可以的,但必须在 from django.contrib.auth.decorators import permission_required
之前完成。
5
在你的测试用例的设置方法中,直接用超级用户登录就可以了。
from django.test import TestCase
from django.contrib.auth.models import User
class TestThatNeedsLogin(TestCase):
def setUp(self):
User.objects.create_superuser(
'user1',
'user1@example.com',
'pswd',
)
self.client.login(username="user1", password="pswd")
def tearDown(self):
self.client.logout()
def test_something(self):
response = self.client.get("/")
self.assertEqual(200, response.status_code)