测试 PermissionRequiredMixin 引发 PermissionDenied 而不是 403

Gam*_*aSQ 5 python django tdd unit-testing

我正在使用 django 1.10.5 和 PermissionRequiredMixin。
如果他们没有正确的权限,我不想将用户重定向到登录名,而是返回 403 错误。
理论上,如果在任何地方引发 PermissionDenied,则响应对象的 status_code 应为 403:

测试客户端不可见的唯一例外是 Http404、PermissionDenied、SystemExit 和 SuspiciousOperation。Django 在内部捕获这些异常并将它们转换为适当的 HTTP 响应代码。在这些情况下,您可以在测试中检查 response.status_code。

从文档:https : //docs.djangoproject.com/en/1.10/topics/testing/tools/#exceptions

但是,我的测试停止在异常 django.core.exceptions.PermissionDenied 这是最简单的 test.py:

from django.test import TestCase, RequestFactory
from doingTests.views import ViewWithPermission
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied

class TestPermission(TestCase):
    def test_permission_view(self):
        user = User.objects.create(username="john", password="doh")
        permView = ViewWithPermission.as_view()
        rf = RequestFactory()
        request = rf.get('/test/')
        request.user = user
        self.assertEqual(permView(request).status_code, 403)
Run Code Online (Sandbox Code Playgroud)

有了这个 view.py:

from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic.base import TemplateView

class ViewWithPermission(PermissionRequiredMixin, TemplateView):
    permission_required="doingTests.add_mock"
    raise_exception=True
Run Code Online (Sandbox Code Playgroud)

需要什么权限其实并不重要,随机字符串、自定义权限和内置权限都会引发PermissionDenied。

由于这里有很多变量,我可能只是遗漏了一些东西,例如permission_required 需要一个permission-object 而不是一个字符串(试过了)。


我误解了以下内容,更正如下:

但是我开始认为这可能是一个错误,因为测试 PermissionDenied Exception 仍然会引发异常而不是通过测试!
将 test.py 中的最后一行更改为:

self.assertRaises(PermissionDenied, permView(request))
Run Code Online (Sandbox Code Playgroud)

如果处理得当,一切正常,这需要 with-语句:

with self.assertRaises(PermissionDenied):
    permView(request)
Run Code Online (Sandbox Code Playgroud)

不引发异常,测试通过。我仍然想测试错误代码。

All*_*lis 0

这是问题中发布的类似答案,但适用于 pytest:

def test_my_view_for_users_with_permission(self):

    user = UserFactory()
    path = reverse("my_view")
    request = RequestFactory().get(path)
    request.user = user

    with pytest.raises(PermissionDenied) as e_info:
        MyView.as_view()(request)
Run Code Online (Sandbox Code Playgroud)

如果MyView.as_view()(request)引发PermissionDenied异常,则测试通过。

在我的示例UserFactory()中,是DjangoModelFactory在另一个名为的文件中定义的类factories.py