我正在测试一组广泛使用'permission_required'装饰器的Django应用程序。这在我拥有的大多数视图中都得到了302 HTTP响应。
我的问题是:在测试中有什么方法可以避免或停用'permission_required',所以当我调用我的视图而不是302时,我可以获得200响应?
谢谢!
答案 0 :(得分:5)
只需在测试用例setUp方法中使用超级用户登录
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)
答案 1 :(得分: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
之前。
答案 2 :(得分:0)
好。我找到的解决方案是在TestCase类的setUp方法中创建一个超级用户。我是这样做的:
def setUp(self):
self.client = Client()
self.user = User.objects.create_superuser(
'testuser',
'test@example.com',
'easy_password',
)
然后,当我想测试一个URL时,我这样做:
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)
这对我有用:)
谢谢大家。欢呼声,
何