我在测试ViewSet时遇到问题:
class ViewSetTest(TestCase):
def test_view_set(self):
factory = APIRequestFactory()
view = CatViewSet.as_view()
cat = Cat(name="bob")
cat.save()
request = factory.get(reverse('cat-detail', args=(cat.pk,)))
response = view(request)
我试图在这里复制语法:
http://www.django-rest-framework.org/api-guide/testing#forcing-authentication
但我认为他们的AccountDetail视图与我的ViewSet不同,所以我从最后一行收到此错误:
AttributeError: 'NoneType' object has no attributes 'items'
这里有正确的语法还是我混淆概念?我的APIClient测试工作正常,但我在这里使用工厂是因为我最终想要添加" request.user = some_user"。提前谢谢!
哦,客户端测试工作正常:
def test_client_view(self):
response = APIClient().get(reverse('cat-detail', args=(cat.pk,)))
self.assertEqual(response.status_code, 200)
答案 0 :(得分:16)
我认为我找到了正确的语法,但不确定它是否是传统的(对Django来说还是新的):
def test_view_set(self):
request = APIRequestFactory().get("")
cat_detail = CatViewSet.as_view({'get': 'retrieve'})
cat = Cat.objects.create(name="bob")
response = cat_detail(request, pk=cat.pk)
self.assertEqual(response.status_code, 200)
所以现在这个传递了,我可以分配request.user,它允许我自定义CatViewSet下的检索方法来考虑用户。
答案 1 :(得分:10)
我遇到了同样的问题,并且能够找到解决方案。
查看源代码,看起来视图期望有一个参数'actions',它有一个方法项(所以,一个字典)。
https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/viewsets.py#L69
这就是你得到的错误来自哪里。您必须使用包含该视图集的允许操作的dict指定参数操作,然后您才能正确测试视图集。
一般映射:
{
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
}
http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers
在您的情况下,您需要{'get':'retrieve'} 像这样:
class ViewSetTest(TestCase):
def test_view_set(self):
factory = APIRequestFactory()
view = CatViewSet.as_view(actions={'get': 'retrieve'}) # <-- Changed line
cat = Cat(name="bob")
cat.save()
request = factory.get(reverse('cat-detail', args=(cat.pk,)))
response = view(request)
编辑:您实际上需要指定所需的操作。更改了代码和注释以反映这一点。
答案 2 :(得分:8)
我找到了一种方法,无需手动创建正确的视图集并为其提供动作映射:
from django.core.urlresolvers import reverse, resolve
...
url = reverse('cat-list')
req = factory.get(url)
view = resolve(url).func
response = view(req)
response.render()
答案 3 :(得分:3)
我认为这是你的最后一句话。您需要调用CatViewSet as_view()。我会选择:
response = view(request)
鉴于您已定义view = CatViewSet.as_view()
编辑:
你能展示你的views.py
吗?具体来说,你使用了什么样的ViewSet
?我正在挖掘DRF代码,看起来您可能没有映射到ViewSet的任何操作,这会触发错误。
答案 4 :(得分:1)
我需要使用强制身份验证进行工作,最后得到它,这是我的测试用例:
from django.test import TestCase
from rest_framework.test import APIRequestFactory
from django.db.models.query import QuerySet
from rest_framework.test import force_authenticate
from django.contrib.auth.models import User
from config_app.models import Config
from config_app.apps import ConfigAppConfig
from config_app.views import ConfigViewSet
class ViewsTestCase(TestCase):
def setUp(self):
# Create a test instance
self.config = Config.objects.create(
ads='{"frequency": 1, "site_id": 1, "network_id": 1}',
keys={}, methods={}, sections=[], web_app='{"image": 1, "label": 1, "url": 1}',
subscriptions=[], name='test name', build='test build', version='1.0test', device='desktop',
platform='android', client_id=None)
# Create auth user for views using api request factory
self.username = 'config_tester'
self.password = 'goldenstandard'
self.user = User.objects.create_superuser(self.username, 'test@example.com', self.password)
def tearDown(self):
pass
@classmethod
def setup_class(cls):
"""setup_class() before any methods in this class"""
pass
@classmethod
def teardown_class(cls):
"""teardown_class() after any methods in this class"""
pass
def shortDescription(self):
return None
def test_view_set1(self):
"""
No auth example
"""
api_request = APIRequestFactory().get("")
detail_view = ConfigViewSet.as_view({'get': 'retrieve'})
response = detail_view(api_request, pk=self.config.pk)
self.assertEqual(response.status_code, 401)
def test_view_set2(self):
"""
Auth using force_authenticate
"""
factory = APIRequestFactory()
user = User.objects.get(username=self.username)
detail_view = ConfigViewSet.as_view({'get': 'retrieve'})
# Make an authenticated request to the view...
api_request = factory.get('')
force_authenticate(api_request, user=user)
response = detail_view(api_request, pk=self.config.pk)
self.assertEqual(response.status_code, 200)
我正在将它与django-nose测试运行程序一起使用,它似乎运行良好。希望它对那些在其视图集上启用身份验证的人有所帮助。