Kur*_*eek 1 python django django-rest-framework
我正在尝试使用login_required装饰器将现有的基于函数的视图替换为使用ModelViewSet. 但是,身份验证的工作方式似乎有所不同。
为了尝试使我的单元测试适应 Django REST 框架案例,我克隆了https://github.com/encode/rest-framework-tutorial并tests.py在顶级目录中添加了一个:
import json
from django.contrib.auth.models import User
from django.test import TestCase, Client
from snippets.models import Snippet
class SnippetTestCase(TestCase):
def setUp(self):
self.username = 'john_doe'
self.password = 'foobar'
self.user = User.objects.create(username=self.username, password=self.password)
self.client = Client()
self.snippet = Snippet.objects.create(owner=self.user, code="Foo Bar")
def test_1(self):
self.client.login(username=self.username, password=self.password)
response = self.client.post(
path='http://localhost:8000/snippets/1/',
data=json.dumps({'code': 'New code'}),
content_type="application/json")
self.assertEqual(response.status_code, 201)
Run Code Online (Sandbox Code Playgroud)
但是,这会返回一个403 Forbidden响应:
Kurts-MacBook-Pro:rest-framework-tutorial kurtpeek$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_1 (tutorial.tests.SnippetTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kurtpeek/Documents/source/rest-framework-tutorial/tutorial/tests.py", line 23, in test_1
self.assertEqual(response.status_code, 201)
AssertionError: 403 != 201
----------------------------------------------------------------------
Ran 1 test in 0.049s
FAILED (failures=1)
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)
另一方面,使用带有-a标志的HTTPie工作正常:
Kurts-MacBook-Pro:rest-framework-tutorial kurtpeek$ http -a kurtpeek:foobar123 POST http://localhost:8000/snippets/ code="print 123"
HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 212
Content-Type: application/json
Date: Thu, 25 Jan 2018 00:11:59 GMT
Location: http://localhost:8000/snippets/2/
Server: WSGIServer/0.2 CPython/3.6.4
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
{
"code": "print 123",
"highlight": "http://localhost:8000/snippets/2/highlight/",
"id": 2,
"language": "python",
"linenos": false,
"owner": "kurtpeek",
"style": "friendly",
"title": "",
"url": "http://localhost:8000/snippets/2/"
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这个测试应该满足IsOwnerOrReadonly权限类的要求:
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
# Write permissions are only allowed to the owner of the snippet.
return obj.owner == request.user
Run Code Online (Sandbox Code Playgroud)
因为这User也是owner片段的。任何想法为什么这不起作用,或者我如何构建通过的测试用例?
我发现 Django REST 框架有自己的一套测试工具。现在,我从而不是从子类rest_framework.test.APITestCase化django.test.TestCase,并.force_authenticate在这样创建的上调用方法self.client:
import json
from django.contrib.auth.models import User
from django.test import TestCase
from rest_framework.test import APITestCase, force_authenticate
from snippets.models import Snippet
class SnippetTestCase(APITestCase):
def setUp(self):
self.username = 'john_doe'
self.password = 'foobar'
self.user = User.objects.create(username=self.username, password=self.password)
self.client.force_authenticate(user=self.user)
def test_1(self):
response = self.client.post('/snippets/', {'code': 'Foo Bar'}, format='json')
self.assertEqual(response.status_code, 201)
Run Code Online (Sandbox Code Playgroud)
现在测试通过了。
| 归档时间: |
|
| 查看次数: |
3441 次 |
| 最近记录: |