2017-02-06 1 views
0

Ich versuche eine Umfrage-App mit dem Django-Test-Client zu testen. In diesem Test erstelle ich eine POST-Anfrage, die eine Abstimmung über die Umfrage macht und überprüft dann sowohl den Statuscode der Antwort (um zu überprüfen, dass ich umgeleitet wurde) und überprüft die Anzahl der Stimmen hat zugenommen. Also von dem, was ich gelesen habe, meine tests.py beendet aussehen wie diese:Testen einer Umfrage-App mit dem Django-Test-Client

from django.test import Client 
from django.test import TestCase 
from mysite.polls.models import Question, Choice 

class PollTest(TestCase): 

    def test_voting(self): 
     client = Client() 
     # Perform a vote on the poll by mocking a POST request. 
     response = client.post('/polls/1/vote/', {'choice': '1',}) 
     # In the vote view we redirect the user, so check the 
     # response status code is 302. 
     self.assertEqual(response.status_code, 302) 
     # Get the choice and check there is now one vote. 
     choice = Choice.objects.get(pk=1) 
     self.assertEqual(choice.votes, 1) 

und die Abstimmung Teil views.py sieht wie folgt aus:

def vote(request, question_id): 
    question = get_object_or_404(Question, pk=question_id) 
    try: 
     selected_choice = question.choice_set.get(pk=request.POST['choice']) 
    except (KeyError, Choice.DoesNotExist): 
     # Redisplay the question voting form. 
     return render(request, 'polls/detail.html', { 
      'question': question, 
      'error_message': "You didn't select a choice.", 
     }) 
    else: 
     selected_choice.votes += 1 
     selected_choice.save() 
     # Always return an HttpResponseRedirect after successfully dealing 
     # with POST data. This prevents data from being posted twice if a 
     # user hits the Back button. 
     return HttpResponseRedirect(reverse('polls:results', args (question.id,))) 

und meine urls.py sieht wie folgt aus:

from django.conf.urls import url 
from . import views 

app_name = 'polls' 
urlpatterns = [ 
    url(r'^$', views.IndexView.as_view(), name='index'), 
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'), 
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'), 
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), 
    ] 

Das erste Problem, das ich hatte, nachdem ich python manage.py test ausgeführt hatte, war, dass ich den Antwortstatuscode zu 405 ändern musste, wenn es 302 sein sollte , denn nachdem ich die Abstimmung gewählt und auf den Abstimmknopf geklickt habe, werde ich auf /polls/1/results umgeleitet. Darüber hinaus wird die Abstimmung tatsächlich nicht registriert, da nach dem Ändern des Antwortstatuscodes, nur um zu sehen, ob mindestens die Stimme erhöht wurde, der Fehler erhalten wird, dass 1 falsch ist, und es sollte in 0 geändert werden, was den Abstimmungsprozess bedeutet funktioniert auch nicht.

+1

Sie sollten nicht 405 bekommen - das bedeutet 'Methode nicht erlaubt'. Meine Vermutung ist, dass die falsche Ansicht die Anfrage bearbeitet. Bitte zeigen Sie Ihre 'Umfragen/urls.py'. – Alasdair

+0

Beachten Sie, dass Sie 'client = Client()' nicht benötigen. Wenn Sie das Django 'TestCase' verwenden, benutzen Sie einfach' self.client'. – Alasdair

+0

Ich habe meinen Beitrag mit 'views.py' bearbeitet. – Code4fun

Antwort

0

Fügen Sie den folgenden Dekorateur POST ermöglichen:

from django.views.decorators.http import require_http_methods 

@require_http_methods(["POST"]) 
def vote(request, poll_id): # this is your method from above 
    p = get_object_or_404(Poll, pk=question_id) 
    try: 
     ... 

Ansonsten diese Ansicht Griffe GET Methoden standardmäßig. Zur gleichen Zeit möchten Sie wirklich vote() auf POST Anrufe beschränkt werden, weil es Ihre Daten ändert.

Siehe https://docs.djangoproject.com/en/1.10/topics/http/decorators/#django.views.decorators.http.require_http_methods

Im Test Verwendung response = client.post(..., follow=True) Umleitungen zu folgen und das Endergebnis zu testen.

+0

Ich habe gerade nicht verstanden, wo sollte ich den Dekorateur hinzufügen und was ist eigentlich der Zweck davon? – Code4fun

+0

Es könnte eine gute Idee sein, '@require_http_methods ([" POST "])' 'zu verwenden, aber es erklärt das aktuelle Problem nicht. – Alasdair

+0

Nicht registrieren 'POST' kann definitiv ein Grund für einen Fehler 405 und den fehlenden Eintrag in der Datenbank sein. – Risadinha

Verwandte Themen