如何测试视图是否用" login_required" (Django的)

时间:2015-06-19 23:10:06

标签: python django testing decorator login-required

我正在为一个用" login_required"装饰的视图做一些(隔离的)单元测试。例如:

@login_required
def my_view(request):
    return HttpResponse('test')

是否可以测试" my_view"函数用" login_required"?

进行修饰

我知道我可以通过集成测试(使用测试客户端)来测试行为(匿名用户被重定向到登录页面),但我希望通过隔离测试来完成。

有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:5)

当然,必须以某种方式测试它。但是,这绝对不值得。编写完全隔离的单元测试来检查装饰器是否应用只会导致非常复杂的测试。测试错误的可能性高于测试行为错误的可能性。我强烈反对它。

测试它的最简单方法是使用Django的Client伪造对相关网址的请求,并检查重定向。如果您使用任何Django的测试用例作为基类:

class MyTestCase(django.test.TestCase):
    def test_login_required(self):
        response = self.client.get(reverse(my_view))
        self.assertRedirects(response, reverse('login'))

稍微复杂一点,但更加孤立的测试是直接使用RequestFactory调用视图来创建请求对象。 assertRedirects()在这种情况下无法工作,因为它取决于Client设置的属性:

from django.test.client import RequestFactory

class MyTestCase(django.test.TestCase):
    @classmethod
    def setUpClass(cls):
        super(MyTestCase, cls).setUpClass()
        self.rf = RequestFactory()

    def test_login_required(self):
        request = self.rf.get('/path/to/view')
        response = my_view(request, *args, **kwargs)
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response['Location'], login_url)
        ...

答案 1 :(得分:1)

使用 Django的测试客户端检查用户登录时和未登录时是否有正确的重定向。

from django.test import TestCase
from django.core.urlresolvers import reverse

class TestLoginRequired(django.test.TestCase):

    def test_redirects_to_login_page_on_not_loggedin(self):
        response = self.client.get(reverse(my_view))
        self.assertRedirects(response, reverse('login_page'))

    def test_redirects_to_test_page_on_loggedin(self):
        self.client.login(username='my_username', password='my_password')
        response = self.client.get(reverse(my_view))
        self.assertRedirects(response, reverse('test'))

MOCK图书馆:

对于隔离测试或“纯”单元测试,您可以使用mock模块。

模拟是一个用于在Python中进行测试的库。它允许您使用模拟对象替换被测系统的部分,并对如何使用它们进行断言 模拟基于'动作 - >断言'模式而不是'记录 - >重播'被许多模拟框架使用。

您必须创建一个模拟对象。模拟对象在您访问它们时会创建所有属性和方法,并存储它们的使用方式的详细信息。您可以配置它们,指定返回值或限制可用的属性,然后断言它们的使用方式:

使用模拟对象的测试将仅测试my_view函数是否用login_required修饰。您无需设置其他属性。

使用此link查看有关如何使用模拟对象编写测试的文档。

此外,遵循SO链接可能有助于如何修补装饰器。

答案 2 :(得分:-2)

使用requests库,如果您未通过身份验证Cookie,则可以根据是否返回401 / 403/200 /无论

来测试是否需要登录
import requests
req = requests.get("http://yoururl.com")
if req.status_code ==200:
    print "login not needed apparently"
else:
    print "check for other status codes or redirect"