379 Stimmen

Wie kann ich Anfragen und die Antwort nachahmen?

Ich versuche, das Mockpaket von Python zu verwenden, um das Python requests Modul zu mocken. Was sind die grundlegenden Aufrufe, um mich in untenstehendem Szenario zum Laufen zu bringen?

In meiner views.py habe ich eine Funktion, die verschiedene requests.get() Aufrufe mit jeweils einer anderen Antwort macht

def myview(request):
  res1 = requests.get('aurl')
  res2 = request.get('burl')
  res3 = request.get('curl')

In meiner Testklasse möchte ich etwas Ähnliches tun, kann jedoch die genauen Methodenaufrufe nicht herausfinden

Schritt 1:

# Das requests Modul mocken
# Wenn mockedRequests.get('aurl') aufgerufen wird, dann 'a response' zurückgeben
# Wenn mockedRequests.get('burl') aufgerufen wird, dann 'b response' zurückgeben
# Wenn mockedRequests.get('curl') aufgerufen wird, dann 'c response' zurückgeben

Schritt 2:

Meine Ansicht aufrufen

Schritt 3:

Überprüfen, ob die Antwort 'a response', 'b response', 'c response' enthält

Wie kann ich Schritt 1 (Mocken des requests Moduls) abschließen?

1voto

Um die Installation anderer Abhängigkeiten zu vermeiden, sollten Sie eine gefälschte Antwort erstellen. Diese FakeResponse könnte ein Kind von Response sein (Ich glaube, das ist ein guter Ansatz, weil es realistischer ist) oder nur eine einfache Klasse mit den benötigten Attributen.

Einfache Fake-Klasse

class FakeResponse:
        status_code = None

        def __init__(self, *args, **kwargs):
            self.status_code = 500
            self.text = ""

Kind von Response

class FakeResponse(Response):
        encoding = False
        _content = None

        def __init__(*args, **kwargs):
            super(FakeResponse).__thisclass__.status_code = 500
            # Requests erfordert nicht None zu sein, sonst wird eine Ausnahme geworfen
            # Zur Referenz: https://github.com/psf/requests/issues/3698#issuecomment-261115119
            super(FakeResponse).__thisclass__.raw = io.BytesIO()

0voto

Max P Magee Punkte 493

Nur ein hilfreicher Hinweis für diejenigen, die immer noch damit kämpfen, von urllib oder urllib2/urllib3 auf requests umzusteigen und versuchen, eine Antwort zu mocken - ich habe einen etwas verwirrenden Fehler bekommen, als ich mein Mock-Implementierung:

Mit requests.get(path, auth=HTTPBasicAuth('user', 'pass'), verify=False) as url:

AttributeError: __enter__

Nun, natürlich, wenn ich etwas über den Umgang mit wüsste (was ich nicht tat), würde ich wissen, dass es ein überflüssiger, unnötiger Kontext (aus PEP 343) ist. Unnötig bei Verwendung der requests-Bibliothek, da sie im Grunde dasselbe für Sie tut unter der Haube. Entfernen Sie einfach das with und verwenden Sie einfach requests.get(...) und Fertig ist Kees.

0voto

idle sign Punkte 1134

Für pytest-Benutzer gibt es eine praktische Fixture von https://pypi.org/project/pytest-responsemock/

Zum Beispiel, um GET zu mocken http://some.domain können Sie:

def test_me(response_mock):

    with response_mock('GET http://some.domain -> 200 :Nice'):
        response = send_request()
        assert result.ok
        assert result.content == b'Nice'

0voto

Gajanan Punkte 434

Ich werde zeigen, wie Sie Ihre Programmlogik von der tatsächlichen externen Bibliothek trennen können, indem Sie die echte Anfrage durch eine gefälschte ersetzen, die dieselben Daten zurückgibt. In Ihrer Ansicht ist dieser Prozess am besten, wenn externe API-Aufrufe erfolgen.

import pytest
from unittest.mock import patch
from django.test import RequestFactory

@patch("Pfad(Projectname.Appname.Dateiname).Anfragen.post")
def test_mock_response(self, mock_get, rf: RequestFactory):
    mock_get.return_value.ok = Mock(ok=True)
    mock_get.return_value.status_code = 400
    mock_get.return_value.json.return_value = {Hier können Sie eine Dummy-Antwort definieren}
    request = rf.post("test/", data=self.payload)
    response = view_name_view(request)

    expected_response = {
        "success": False,
        "status": "unsuccessful",
    }

    assert response.data == expected_response
    assert response.status_code == 400

0voto

Jake Punkte 106

Wenn pytest verwendet wird:

>>> import pytest
>>> import requests

>>> def test_url(requests_mock):
...     requests_mock.get('http://test.com', text='data')
...     assert 'data' == requests.get('http://test.com').text

Entnommen aus der offiziellen Dokumentation

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X