使用force_authenticate()后Django测试用例仍返回401状态码的问题排查
问题:测试DRF视图时使用
force_authenticate仍返回401状态码 我在测试项目中的jumpStory视图时遇到了问题,即使调用了force_authenticate(),测试请求仍返回<Response status_code=401, "application/json">。
我的测试代码
def test_jump_story(self): c = APIClient() user = User.objects.get(username='test1') c.login(username=user.username, password='123') room_id = PokerRoom.objects.get(name='planning').id room_index = PokerRoom.objects.get(name='planning').index request = c.post(reverse('jumpstory', kwargs={'pk': room_id, 'index': room_index})) c.force_authenticate(user=user) self.assertEqual(200,request.status_code)
对应的视图代码
class jumpStory(APIView): permission_classes = [IsAuthenticated] def post(self, request, pk, index): data= self.request.data index = self.kwargs['index'] pk = self.kwargs['pk'] if PokerRoom.objects.filter(id=pk).exists(): body = {'index':index} message_socket("JUMP_STORY", pk, body) return Response({'success':"JUMP_STORY"}, status=200) else: return Response({'error':'message not sended'}, status=400)
问题分析与解决方案
你的测试代码存在一个关键的顺序错误:你是先发送了POST请求,之后才调用force_authenticate(user=user)。这意味着发送请求时客户端还未完成认证,自然会返回401未授权状态。force_authenticate()必须在发送请求前调用,才能让请求携带认证信息。
另外,你同时使用了c.login()和force_authenticate(),其实两者选其一即可,以下是两种修正方案:
方案一:使用force_authenticate()(测试场景更直接)
def test_jump_story(self): c = APIClient() user = User.objects.get(username='test1') # 先完成认证,再发送请求 c.force_authenticate(user=user) room_id = PokerRoom.objects.get(name='planning').id room_index = PokerRoom.objects.get(name='planning').index request = c.post(reverse('jumpstory', kwargs={'pk': room_id, 'index': room_index})) self.assertEqual(200, request.status_code)
方案二:确保login()生效(需确认用户密码正确性)
def test_jump_story(self): c = APIClient() user = User.objects.get(username='test1') # 先执行登录,验证登录是否成功 login_success = c.login(username=user.username, password='123') self.assertTrue(login_success, "登录失败,请检查用户密码是否正确") room_id = PokerRoom.objects.get(name='planning').id room_index = PokerRoom.objects.get(name='planning').index request = c.post(reverse('jumpstory', kwargs={'pk': room_id, 'index': room_index})) self.assertEqual(200, request.status_code)
额外排查技巧
如果还是有问题,可以打印响应的具体内容,帮助定位错误:
print(request.json())
内容的提问来源于stack exchange,提问作者Enzo Massaki
相关产品推荐
相关产品推荐

