簡體   English   中英

Django Rest Framework - 如何測試ViewSet?

[英]Django Rest Framework - How to test ViewSet?

我在測試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)

我想我找到了正確的語法,但不確定它是否是傳統的(對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下的檢索方法來考慮用戶。

我遇到了同樣的問題,並且能夠找到解決方案。

查看源代碼,看起來視圖期望有一個參數'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)

編輯:您實際上需要指定所需的操作。 更改了代碼和注釋以反映這一點。

我找到了一種方法來做到這一點,而無需手動創建正確的視圖集並給它一個動作映射:

from django.core.urlresolvers import reverse, resolve
...
url = reverse('cat-list')
req = factory.get(url)
view = resolve(url).func
response = view(req)
response.render()

我認為這是你的最后一句話。 您需要調用CatViewSet as_view()。 我會選擇:

response = view(request)

鑒於您已經定義了view = CatViewSet.as_view()

編輯:

你能展示你的views.py嗎? 具體來說,你使用了什么樣的ViewSet 我正在挖掘DRF代碼,看起來您可能沒有映射到ViewSet的任何操作,這會觸發錯誤。

我需要使用強制身份驗證,最后得到它,這是我的測試用例的樣子:

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測試跑步者,它似乎運作良好。 希望它可以幫助那些在其視圖集上啟用了auth的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM