Testing
REST框架包括几个帮助类,可以扩展Django现有的测试框架,并改进对API请求的支持。
APIRequestFactory
扩展 Django 现有的 RequestFactory
class.
Creating test requests
APIRequestFactory类支持与Django标准的RequestFactory类几乎相同的API。这意味着标准的.get(), .post(), .put(), .patch(), .delete(), .head() 和.options()
方法都是可用的。
from rest_framework.test import APIRequestFactory
# Using the standard RequestFactory API to create a form POST request
factory = APIRequestFactory()
request = factory.post('/notes/', {'title': 'new idea'})
Using the format
argument
创建请求体的方法,例如post, put 和 patch
,包含一个 format
参数,这使得使用除多表单数据之外的内容类型可以轻松生成请求。 例如:
# Create a JSON POST request
factory = APIRequestFactory()
request = factory.post('/notes/', {'title': 'new idea'}, format='json')
默认可使用的格式有 'multipart'
和 'json'
。为了与Django现有的 RequestFactory
兼容,默认格式为 'multipart'
。
要支持更广泛的请求格式或更改默认格式,请参阅配置部分.
Explicitly encoding the request body
如果请求体中需要明确的编码,你可以设置 content_type 标志。例如:
request = factory.post('/notes/', json.dumps({'title': 'new idea'}), content_type='application/json')
PUT and PATCH with form data
Django RequestFactory和REST框架APIRequestFactory之间值得注意的一个区别是,多表单数据将被编码用于除.post()以外的方法。
例如,使用APIRequestFactory,您可以像这样做一个PUT的表单请求:
factory = APIRequestFactory()
request = factory.put('/notes/547/', {'title': 'remember to email dave'})
使用Django的RequestFactory,您需要自己对数据进行显式编码:
from django.test.client import encode_multipart, RequestFactory
factory = RequestFactory()
data = {'title': 'remember to email dave'}
content = encode_multipart('BoUnDaRyStRiNg', data)
content_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'
request = factory.put('/notes/547/', content, content_type=content_type)
Forcing authentication
当直接使用请求工厂测试视图时,能够直接验证请求通常很方便,而不必构建正确的身份验证凭据。
要强制验证请求,请使用force_authenticate()方法。
from rest_framework.test import force_authenticate
factory = APIRequestFactory()
user = User.objects.get(username='olivia')
view = AccountDetail.as_view()
# Make an authenticated request to the view...
request = factory.get('/accounts/django-superstars/')
force_authenticate(request, user=user)
response = view(request)`
该方法的签名是 force_authenticate(request,user = None,token = None)
。 进行调用时,可以设置用户和令牌中的一个或两者。
例如,当使用令牌进行强制身份验证时,可能会执行以下操作:
user = User.objects.get(username='olivia')
request = factory.get('/accounts/django-superstars/')
force_authenticate(request, user=user, token=user.token)
Note:当使用 APIRequestFactory
时,返回的是Django标准的 HttpRequest,而不是Rest framwork 的Request对象,该对象只有在生成视图时生成。
这意味着直接在请求对象上设置属性可能并不总是具有你所期望的效果。 例如,直接设置.token将不起作用,直接使用.user只会在会话认证认证时有用。
# Request will only authenticate if `SessionAuthentication` is in use.
request = factory.get('/accounts/django-superstars/')
request.user = user
response = view(request)
Forcing CSRF validation
默认情况下,使用APIRequestFactory创建的请求在传递到REST框架视图时不会应用CSRF验证。 如果需要明确地打开CSRF验证,可以在实例化工厂时设置enforce_csrf_checks标志。
factory = APIRequestFactory(enforce_csrf_checks=True)
Note:值得注意的是,Django的标准RequestFactory不需要包含此选项,因为当使用常规Django时,CSRF验证发生在中间件中,直接测试视图时不会运行。 当使用REST框架时,CSRF验证在视图中进行,因此请求工厂需要禁用视图级别的CSRF检查。
APIClient
扩展了 Django 现有的 Client class.
Making requests
APIClinet 类支持与 Django标准的Client类相同的接口。这意味标准的.get(), .post(), .put(), .patch(), .delete(), .head() 和 .options() 方法都是可用的。例如:
from rest_framework.test import APIClient
client = APIClient()
client.post('/notes/', {'title': 'new idea'}, format='json')
要支持更广泛的请求格式或者改变默认格式,请参阅配置部分。
Authenticating
.login(**kwargs)
登录方法的功能与Django的常规Client类完全相同。 这允许您针对包括SessionAuthentication在内的任何视图验证请求。
# Make all requests in the context of a logged in session.
client = APIClient()
client.login(username='lauren', password='secret')
登出是通常调用 logout 方法。
# Log out
client.logout()
登录方法适用于测试使用会话认证的API,例如包含AJAX与API交互的网站。