0

urls.py中,我的视图详细信息用login_required注释,以将未经授权的用户转发到登录页面:

url(r'^(?P<id>[0-9]+)/$', login_required(views.detail), name = 'detail')

我正在尝试编写一个测试来检查在查询目标 url 时选择了哪个视图。在测试开始之前,我有一堂课要登录:

class LoggedInTestCase(TestCase):
    def setUp(self):
        user = User.objects.create_user('test', 'test@example.com', 'test')
        self.client.login(username='test', password='test')

class ProductDetailTest(LoggedInTestCase):
    def setUp(self):
        super(ProductDetailTest, self).setUp()

    def test_product_detail_url_resolves_product_detail_view(self):
        view = resolve('/products/1/')
        self.assertEquals(view.func, detail)

当我运行测试时,我得到了:

FAIL: test_product_detail_url_resolves_product_detail_view (products.tests.ProductDetailTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\heroku\django\products\tests.py", line 46, in test_product_detail_url_resolves_product_detail_view
    self.assertEquals(view.func, detail)
AssertionError: <function detail at 0x05CC3780> != <function detail at 0x053B38A0>

----------------------------------------------------------------------

检查哪个视图已解决

    print('VIEW: ', view.view_name)

结果是:

test_product_detail_url_resolves_product_detail_view (products.tests.ProductDetailTest) ... VIEW:  products:detail

当我删除login_required时,所有测试都通过了。

4

1 回答 1

1

当你这样做login_required(detail)时,装饰器会返回一个新函数。您的断言应该在测试中失败,因为功能不一样。

这里有几个选项。在视图中使用装饰器可能是最简单的:

@login_required
def detail(request, *args, **kwargs)
    ...

并将网址模式更改为:

url(r'^(?P<id>[0-9]+)/$', views.detail, name = 'detail'),

如果你需要使用未装饰的detail视图,那么你不能像那样使用装饰器。在这种情况下,您分配login_required(detail)给一个新变量,

def detail(request, *args, **kwargs):
    ...

login_required_detail = login_required(detail)

将 URL 模式更改为,

url(r'^(?P<id>[0-9]+)/$', views.login_required_detail, name = 'detail'),

并将测试更改为:

self.assertEquals(view.login_required_detail, detail)
于 2017-10-12T09:00:14.037 回答