尽管这可能不是一个最小的示例,但我正在构建如何使用 Django-oauth-toolkit for authentication 使用 Django-rest-framework 测试 API 端点。我有一个模型Session
,我希望能够使用 Django REST 框架对其进行更新。为此我写了如下视图:
from rest_framework import generics
from oauth2_provider.contrib.rest_framework import OAuth2Authentication
from ..models import Session
from ..serializers import SessionSerializer
class SessionDetail(generics.UpdateAPIView):
authentication_classes = [OAuth2Authentication]
queryset = Session.objects.all()
serializer_class = SessionSerializer
默认permission_classes
设置在settings.py
:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
我编写了以下测试用例:
import json
from django.contrib.auth.models import User
from datetime import timedelta
from django.urls import reverse
from django.test import TestCase, Client
from django.utils import timezone
from rest_framework import status
from ..models import Family, Session, SessionType, SessionCategory
from oauth2_provider.models import get_application_model, get_access_token_model
Application = get_application_model()
AccessToken = get_access_token_model()
class OAuth2TestCase(TestCase):
def setUp(self):
self.username = "test_user"
self.password = "123456"
self.user = User.objects.create_user(username=self.username, password=self.password)
self.application = Application(
name="Test Application",
redirect_uris="http://localhost",
user=self.user,
client_type=Application.CLIENT_CONFIDENTIAL,
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
)
self.application.save()
self.TOKEN = '1234567890'
self.token = AccessToken.objects.create(
user=self.user,
token=self.TOKEN,
application=self.application,
scope='read write',
expires=timezone.now() + timedelta(days=1)
)
self._create_session()
def _create_session(self):
self.session_category = SessionCategory.objects.create(
name='Birth Prep')
self.session_type = SessionType.objects.create(
title='Initial Postpartum Lactation',
category=self.session_category)
self.family = Family.objects.create()
self.session = Session.objects.create(
family=self.family,
session_type=self.session_type)
def test_make_patch_request(self):
data = {'feedback_expert': 'Yes'}
url = reverse('sessions-feedback', kwargs={'pk': self.session.id})
auth = f"Bearer {self.TOKEN}"
response = self.client.patch(
path=url,
data=json.dumps(data),
content_type="application/json",
HTTP_AUTHORIZATION=auth,
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Session.objects.get(pk=self.session.id).feedback_expert, 'Yes')
# self.assertEqual(self.session.feedback_expert, 'Yes')
测试通过了,但让我感到困惑的是,如果我在最后一行评论而不是
self.assertEqual(self.session.feedback_expert, 'Yes')
我得到一个测试失败:
(venv) Kurts-MacBook-Pro:lucy-web kurtpeek$ python manage.py test lucy_web.tests.test_feedback
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_make_patch_request (lucy_web.tests.test_feedback.OAuth2TestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/lucy_web/tests/test_feedback.py", line 295, in test_make_patch_request
self.assertEqual(self.session.feedback_expert, 'Yes')
AssertionError: '' != 'Yes'
+ Yes
----------------------------------------------------------------------
Ran 1 test in 1.299s
FAILED (failures=1)
Destroying test database for alias 'default'...
显然,self.session
它的feedback_expert
字段还没有更新,而返回的字段却更新了Session.objects.get(pk=self.session.id)
。知道为什么会这样吗?