使用 Django 测试客户端测试 UserPassesTestMixin

Testing UserPassesTestMixin with django test client

我已经使用 UserPassesTestMixin 保护了基于 django class 的视图。它的 test_func 接受一个名为 division 的参数,并检查当前用户是否是该部门的负责人。

该视图在站点中运行完美,但我无法编写成功的测试。似乎在 client.get 和 test_func 之间,用户正在消失。

我已经用 RequestFactory 和 Client 试过了。我试过强制登录。确保正确的中间件就位。

mixin 的测试没有帮助我发现问题。 ( https://github.com/django/django/blob/29f607927fe82e2c8baab171dfa8baf710cd9b83/tests/auth_tests/test_mixins.py )

现在我无法针对受 UserPassesTestMixin 保护的视图测试各种角色。对于为什么当我使用 client.login(username='div1chair', password='basicpassword') 登录时,我将不胜感激self.request.user 在视图本身中。

def test_permissions_to_access_division_summary_view(self):
        """
        This test ensures that only department chairs and the division
        director for the specific division detail can see the division
        summary.
        """
        url = "/division1"

        client = Client()
        client.login(username='div1chair', password='basicpassword')

        # ipdb here confirms that div1chair is logged in
        # ETA: ut oh.  looks like this is not accurate. Now I'm really confused. client.login is giving False.

        response = client.get(url,follow=True)
        self.assertEqual(response.status_code, 200) # AssertionError: 404 != 200

这是我正在测试的视图。

class DivisionDirectorView(UserPassesTestMixin, View):

    def test_func(self):     

        division = Division.objects.get(short_name=self.kwargs['division'])

        # ipdb here confirms that there is no user, or at least username is ''
        if self.request.user == division.director:
            return True

        return False

预计到达时间:urls.py:

from django.conf.urls import url
from fds.apps.professionalmetrics import views

urlpatterns = [
    url(r'^$', views.metrics_default, name='metrics_default'),
    # SNIP
    url(r'(?P<division>[\w-]+)/$',
        views.DivisionDirectorView.as_view(),
        name='div-metric-summary'),
    ]

您的 test_funcdispatch 方法不寻常 - UserPassesTest 混入的 test_func 不应该接受除 self 之外的任何参数。我会将 test_func 简化为以下内容:

def test_func(self):     
    division = Division.objects.get(short_name=self.kwargs['division'])
    return self.request.user == division.director

那么您应该能够从 dispatch 方法中删除自定义代码。

但是,我不确定这是否会解决您在测试中发现的问题。您还没有显示您的网址,所以我无法判断 client.get(url, follow=True) 是否应该 return 200 或是否需要 404。您可以通过设置 follow = False 并检查 response.

来尝试调试