2012-04-13 4 views
7

Ich habe eine Funktion, die ich von einem Unittest anrufe. Vom Setzen einiger Debug-Traces weiß ich, dass die Funktion wie ein Charm funktioniert und alle Werte korrekt für die Rückgabe vorbereitet sind.Kann ich auf den Antwortkontext einer Ansicht zugreifen, die ohne den Testclient getestet wurde?

Dies ist, was mein Testcode aussieht (siehe wo mein ipdb.set_trace() ist):

@override_settings(REGISTRATION_OPEN=True) 
def test_confirm_account(self): 
    """ view that let's a user confirm account creation and username 
     when loggin in with social_auth """  
    request = self.factory.get('') 
    request.user = AnonymousUser() 
    request.session={} 
    request.session.update({self.pipename:{'backend':'facebook', 
              'kwargs':{'username':'Chuck Norris','response':{'id':1}}}}) 

    # this is the function of which i need the context: 
    response = confirm_account(request) 
    self.assertEqual(response.context['keytotest'],'valuetotest') 

Von dem, was ich weiß, von this part of the Django docs, i response.context zuzugreifen Lage wäre, wenn ich verwendet habe der Test-Client. Aber wenn ich versuche, response.context zuzugreifen, wie ich es tat, ich diese:

AttributeError: 'HttpResponse' object has no attribute 'context'

Gibt es eine Möglichkeit, das besondere Httpresponse-Objekt des Kunden zu erhalten, ohne den Client zu verwenden?

Antwort

-3

Kontext (sic!) Kann in der Antwortklasse gefunden werden. Wie Sie sehen, es ist HTTP Antwort erhalten Sie von der Ansicht-Funktion zurück. Dies ist passiert, weil Sie es direkt aufgerufen haben. Rufen Sie diese Funktion über den Test-Client auf und es wird in Ordnung sein.

response = client.get('/fobarbaz/') 
response.context 
+0

Der Aufruf über den Test-Client gibt mir keine volle Kontrolle über die Konstruktion der Anfrage. Ich fragte ausdrücklich, ob es ohne den Kunden möglich ist. – marue

+0

Ich manipuliere Sitzung mit dem eingebauten Client in meinen Tests (siehe client.session). Ist das, was Sie nennen, Baukontrolle anfordern? Wenn ja, überdenken Sie Ihren Downvote. – starenka

+2

Nein, ist es nicht. Bei einer Sitzung handelt es sich um Informationen zu einem bestimmten Benutzer, die auf der Serverseite gespeichert sind. Die Anforderung besteht darin, was ein Client an den Server sendet, um eine Serverantwort anzufordern. Der Antwortkontext (den ich verlangte) wird nur zum Testen verwendet und enthält Informationen darüber, wie der Server die Antwort erstellt hat (dh welche Vorlagen verwendet wurden). Es ist nicht derselbe wie der Anfragekontext und nicht derselbe wie die Sitzung. – marue

8

Die RequestFactory berührt nicht die Django-Middleware, und als solche, werden Sie nicht einen Kontext (das heißt keine ContextManager Middleware) erzeugen.

Wenn Sie den Kontext testen möchten, sollten Sie den Testclient verwenden. Sie können immer noch den Aufbau der Anfrage im Test-Client manipulieren entweder Mock oder einfach mit Ihrer Sitzung vor der Zeit in dem Test speichern, wie zum Beispiel:

from django.test import Client 
c = Client() 
session = c.session 
session['backend'] = 'facebook' 
session['kwargs'] = {'username':'Chuck Norris','response':{'id':1}} 
session.save() 

Nun, wenn Sie die Ansicht mit dem Test-Client laden , verwenden Sie die Sitzung so, wie Sie sie festgelegt haben, und wenn Sie response = c.get('/yourURL/') verwenden, können Sie dann wie gewünscht auf den Antwortkontext unter Verwendung von response.context verweisen.

1

Obwohl dies eine alte Post ist, kann dieser Tipp hilfreich sein. Sie können unter Verwendung von TemplateResponse (oder SimpleTemplateResponse) suchen, die für render oder render_to_response ersetzt werden können.

Die Django docs hat mehr zu diesem

0

Ja, Sie können. Sie müssen das Rendering patchen.

Ich verwende pytest-django

class Test: 
    def context(self, call_args): 
     args, kwargs = call_args 
     request_mock, template, context = args 
     return context 

    @patch('myapplication.views.render') 
    def test_(self, mock_render, rf): 
     request = rf.get('fake-url') 
     view(request) 
     context = self.context(mock_render.call_args) 

     keytotest = 'crch' 
     assert keytotest == context['keytotest'] 
0

Die „response.context“ ist falsch, aber sie response.context_data verwenden den gleichen Kontext zu erhalten, die zu TemplateResponse weitergegeben.

+0

Sie sind downvoted, aber das ist richtig.'response.context' ist ein' ContextList'-Objekt, während 'response.context_data' ein Dictionary ist, das wie die' Context'-Instanz strukturiert ist, die an die Vorlage übergeben wird. –

Verwandte Themen