【问题标题】:How to test that a view is only accessed by staff users in Django如何测试视图是否只能由 Django 中的员工用户访问
【发布时间】:2016-02-08 23:51:29
【问题描述】:

我正在学习 Django 中的测试,并且有一个我想要测试的视图。此视图只能由员工用户访问。假设视图是:

def staff_users(request):
    ....
    # some logic

    return HttpResponseRedirect('/repositories/')

如果请求来自员工用户,它应该重定向到存储库,否则我应该得到类似permission denied 的东西。我从tests.py 之类的东西开始。

 def test_request_object(self):
        self.user = User.objects.create_user(
        username='abc', email='abc@gmail.com', password='1234')
        request = HttpRequest()
        # User send a request to access repositories
        response = staff_users(request)
        self.assertIsNone(response)

问题就在这里,我没有将我的请求对象与任何用户相关联,而且我也了解了from django.contrib.admin.views.decorators import staff_member_required,但不知道如何在这里使用它们。谁能告诉我应该如何测试我的view 只能由staff users 访问?

【问题讨论】:

    标签: python django django-testing python-decorators django-tests


    【解决方案1】:

    您需要做的就是decorate您要保护的视图,如下所示:

    @staff_member_required
    def staff_users(request):
        ....
        # some logic
    
        return HttpResponseRedirect('/repositories/')
    

    如果您想要一个自定义逻辑来测试而不是使用 django 装饰器,那么您也可以编写自己的装饰器。

    def staff_users_only(function):
      def wrap(request, *args, **kwargs):
    
            profile = request.session['user_profile']
            if profile is True: #then its a staff member
                 return function(request, *args, **kwargs)
            else:
                return HttpResponseRedirect('/')
    
      wrap.__doc__=function.__doc__
      wrap.__name__=function.__name__
      return wrap
    

    并将其用作:

    @staff_users_only
    def staff_users(request):
        ....
        # some logic
    
        return HttpResponseRedirect('/repositories/')
    

    编辑

    sessions 在请求对象上的关联以进行测试可以如下完成:

    def test_request_object(self):
        self.user = User.objects.create_user(
        username='abc', email='abc@gmail.com', password='1234')
        request = HttpRequest()
        #create a session which will hold the user profile that will be used in by our custom decorator
        request.session = {} #Session middleware is not available in UnitTest hence create a blank dictionary for testing purpose
        request.session['user_profile'] = self.user.is_staff #assuming its django user.
    
        # User send a request to access repositories
        response = staff_users(request)
    
        #Check the response type for appropriate action
        self.assertIsNone(response)
    

    编辑 2

    使用 django Client 库进行测试也是一个更好的主意:

    >>> from django.test import Client
    >>> c = Client()
    >>> response = c.post('/login/', {'username': 'abc', 'password': '1234'})
    >>> response.status_code
    200
    >>> response = c.get('/user/protected-page/')
    >>> response.content
    b'<!DOCTYPE html...
    

    【讨论】:

    • 请在def wrap(request, ...前面显示标准的全装修方式:@wraps(function)
    • 但是测试用例呢,我将如何将我的请求与员工用户或普通用户相关联?
    • 如果你看到我的test function,我正在使用request = HttpRequest() 来获取请求对象。如何将我的请求对象与员工或普通用户关联?
    • @Pynchia 请多解释,我不清楚你的意思。
    • Anand 现在完全有道理了 :) 希望我能多次投票。让我测试一下你的建议,然后接受。
    猜你喜欢
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 2016-12-20
    • 2023-03-12
    • 2015-09-06
    • 2022-11-09
    • 2019-03-26
    相关资源
    最近更新 更多