2016-11-01 2 views
4

Zu Testzwecken versuche ich ein Response() - Objekt in Python zu erstellen, aber es erweist sich als schwieriger, als es klingt.Erstellen Sie ein funktionierendes Response-Objekt

Ich habe versucht, dies:

from requests.models import Response 

the_response = Response() 
the_response.code = "expired" 
the_response.error_type = "expired" 
the_response.status_code = 400 

aber wenn ich the_response.json() versucht bekam ich einen Fehler, da die Funktion len(self.content) und a.content null zu bekommen versucht. Also ich setze a._content = "{}" aber dann bekomme ich einen Kodierungsfehler, also muss ich a.encoding ändern, aber dann kann es den Inhalt nicht dekodieren .... das geht weiter und weiter. Gibt es eine einfache Möglichkeit, ein Response-Objekt zu erstellen, das funktional ist und einen beliebigen status_code und Inhalt hat?

+0

Haben Sie in Betracht gezogen, etwas wie [Antworten] (https://github.com/getsentry/responses) zu verwenden? Alternativ erstellen Sie ein ["Mock"] (https://docs.python.org/3/library/unittest.mock.html), anstatt zu versuchen, das reale Objekt neu zu erstellen. – jonrsharpe

Antwort

9

Das _content Attribut auf die Response Objekte (auf Python3) muss Bytes und nicht Unicodes sein.

Hier ist, wie es zu tun:

from requests.models import Response 

the_response = Response() 
the_response.code = "expired" 
the_response.error_type = "expired" 
the_response.status_code = 400 
the_response._content = b'{ "key" : "a" }' 

print(the_response.json()) 
+0

Dies funktioniert, bricht aber, wenn sich 'requests' ändern die Umsetzung von "Response"; Der führende Unterstrich weist auf ein internes Detail hin, auf das man sich nicht verlassen sollte. Das heißt, es hat sich für eine Weile nicht geändert (und eine solche Änderung kann auch Auswirkungen darauf haben, wie "Antworten" ihre Sache machen, es sei denn, sie verspotten auch die öffentliche Schnittstelle). – jonrsharpe

+0

100% einverstanden, aber wie OP-Frage - das ist die richtige Lösung. Upvoted auch Ihre falsche Lösung (viel besser als 3th Party lib), aber wieder fragte das OP nach bestimmten Anwendungsfall und wollte wissen, warum sein Code nicht funktioniert. –

2

einfach die responses Bibliothek nutzen es für Sie zu tun:

import responses 

@responses.activate 
def test_my_api(): 
    responses.add(responses.GET, 'http://whatever.org', 
        json={}, status=400) 

    ... 

Dies hat den Vorteil, dass es eine echte Anfrage abfängt, anstatt um irgendwo eine Antwort zu injizieren.

5

erstellen mock Objekt, anstatt zu versuchen, einen echten, einen zu bauen:

from unittest.mock import Mock 

from requests.models import Response 

the_response = Mock(spec=Response) 

the_response.json.return_value = {} 
the_response.status_code = 400 

Bereitstellung einer spec sorgt dafür, dass das Mock wird sich beschweren, wenn Sie nicht über eine echte Response den Zugriff auf Methoden und Attribute versuchen.

Verwandte Themen