在单元测试中设置 HttpReferrer

Setting HttpReferrer In Unit Tests

在我的 view.py 中,我对几个连续的页面进行了以下检查:

if(request.META.get('HTTP_REFERER') != request.build_absolute_uri(reverse('page1'))):
            return redirect('page1')

这在每个页面上执行,检查用户是否从上一页重定向,因此(例如)如果用户尝试在地址栏中输入第 4 页的 url,测试将失败,他将被发送到 page3,然后该页面测试将失败,他将返回到 page2,依此类推。

我这样做是因为我有几个链接在一起的页面,用户必须连续访问这些页面。

当我要进行单元测试时,问题就来了。以下测试将抛出错误,因为它未通过重定向测试,因此无法测试我正在尝试测试的页面的逻辑:

def test_user_information_updated_on_validation_success(self):
        user = User.objects.create_superuser('username')
        self.client.force_login(user)

        self.client.post(reverse('page_4'), {
            'exampleQuestion': 'exampleAnswer'
        })
        user.refresh_from_db()

        self.assertEqual(user.exampleform.somefield, 'exampleAnswer')

如何在单元测试中访问页面,就像它已被重定向一样。

谢谢。

测试客户端中的请求接受映射到 WSGI 环境变量的关键字。以 HTTP 开头且全部大写的环境变量,破折号映射到下划线 - 是 Http headers,所以简短的版本是我们可以这样设置 HTTP headers:

# Wrong: Generates absolute paths without hosts
self.client.post(
    reverse('page_4'), {'exampleQuestion': 'exampleAnswer'},
    HTTP_REFERER=reverse('page_3')
)

编辑: 有点太简单了,因为 HTTP referrers 是全限定的,所以我们需要:


referer = 'http://testserver{}'.format(reverse('page_3'))
self.client.post(
    reverse('page_4'), {'exampleQuestion': 'exampleAnswer'},
    HTTP_REFERER=referer
)

仅供参考:协议 (wsgi.scheme) 和主机名 (HTTP_SERVER) 来自 djang.test.client.RequestFactory._base_environ()。如果您使用更改了 servername and/or 协议的修改客户端,您应该相应地进行调整。在这种情况下,明智的做法是在修改后的测试客户端中覆盖 _base_environ 并从中获取值。