[PYTHON] Ist es in Ordnung mit einem solchen Patch? (Memo über Mock ~ Part 2 ~)

Mir geht es nicht gut. Es ist ein Problem.

Als ich das Modell verwendete, das ich in Vorheriger Artikel geschrieben hatte, war ich süchtig nach ungefähr 2 Punkten.

Das Patch-Ziel muss abhängig von der Importmethode geändert werden

Betrachten Sie den Fall des Testens eines Moduls, das eine externe Bibliothek verwendet, wie folgt. (In den folgenden Beispielen wird die http-Bibliothek Anfragen als externe Bibliothek verwendet. Einige der folgenden Beschreibungen hängen von Anfragen ab. Es sind die Inhalte, die gemacht wurden.) Um dieses Modul alleine zu testen, können Sie die Klassen in der externen Bibliothek verspotten.

python:Zu testendes Modul(A.target.Lass es py sein)


from requests import Session

#Verwenden Sie die Session-Klasse irgendwo
s = Session()

Wenn Sie hier wie folgt schreiben, können Sie die externe Bibliothek nicht gut verspotten.

Externe Bibliothek verspotten(Error)


import A

from mock import patch

# A.Verspotten der im Ziel verwendeten Sitzungsklasse(ich gehe)
with patch('requests.Session'):
	#Prüfung

Der Punkt ist, wie die externe Bibliothek in das zu testende Modul importiert wird.

Wenn "From Requests Import Session" angegeben ist, wird die Session-Klasse unter dem Modulbereich platziert, in dem der Import ausgeführt wurde. Wenn das zu testende Modul "A.target.py" ist, ist es "A.target.Session".

Das zu testende Modul verwendet die darunter importierte Session-Klasse (A.target.Session), daher müssen Sie dies verspotten.

Externe Bibliothek verspotten(richtig)


import A

from mock import patch

# A.Verspotten der in das Ziel importierten Sitzungsklasse
with patch('A.target.Session'):
	#Prüfung

Was ist andererseits, wenn Sie "Importanfragen" sagen?

Zu testendes Modul(Wenn Sie nicht von verwenden)


import requests

#Verwenden Sie die Session-Klasse irgendwo
s = requests.Session()

Anstatt die von mir kontrollierte Sitzungsklasse zu importieren, gebe ich diesmal "request.Session" und das Paket der externen Bibliothek an. Daher ist das Scheinziel nicht "A.target.Session", sondern "request.Session".

Externe Bibliothek verspotten(Wenn Sie nicht von verwenden)


import A

from mock import patch

#Verspotten der Sitzungsklasse im Anforderungspaket
with patch('requests.Session'):
	#Prüfung

Vorsichtsmaßnahmen beim Verspotten von Eigenschaften

Mit patch wird auch das angegebene Zielattribut (Methode usw.) automatisch verspottet. In diesem Fall wird standardmäßig die Mock-Klasse MagicMock verwendet.

Beispiel für das Verspotten des Attributs des angegebenen Ziels


>>> import requests
>>> from mock import patch

# requests.Die Post-Methode der Session-Klasse wird verspottet
>>> with patch('requests.Session'):
    s = requests.Session()
    print(s.post)
...
<MagicMock name='Session().post' id='4401343792'>

Stellen Sie sich den Fall vor, in dem das Antwortmodell als Rückgabewert der Post-Methode der Anforderungen festgelegt wird. Die oben automatisch verspottete Sitzungsklasse. Da die Antwort der Post-Methode eine 'Text'-Eigenschaft hat, wird angenommen, dass dieselbe Eigenschaft (Mock) in der zu erstellenden Mock-Antwort festgelegt ist.

Verwenden Sie PropertyMock, um Eigenschaften zu verspotten. Selbst wenn Sie MagicMock verwenden, können Sie den Rückgabewert der Eigenschaft nicht angeben (= Rückgabewert des Getters).

Verwenden Sie MagicMock für Eigenschaften(Fehler)


>>> import requests
>>> from mock import patch, MagicMock

>>> with patch('requests.Session'):
    s = requests.Session()
    response = MagicMock()
    # 'text'Mock-Eigenschaften mit MagicMock(versuchen zu)
    text = MagicMock()
    text.return_value = 'property'
    response.text = text
    s.post.return_value = response
    print(s.post().text)
...

# text.return_Der für value angegebene Wert wird nicht zurückgegeben
<MagicMock name='Session().post().text' id='4506288536'>

Das einfache Ersetzen von MagicMock durch PropertyMock ändert jedoch nichts am Ergebnis.

Verwenden Sie PropertyMock für Eigenschaften(Fehler)


>>> import requests
>>> from mock import patch, MagicMock, PropertyMock

>>> with patch('requests.Session'):
    s = requests.Session()
    response = MagicMock()
    #Verwenden Sie PropertyMock anstelle von MagicMock
    text = PropertyMock()
    text.return_value = 'property'
    response.text = text
    s.post.return_value = response
    print(s.post().text)
...

#Funktioniert immer noch nicht...
<PropertyMock name='Session().post().text' id='4506377240'>

Dies ist ein Problem, das auftritt, wenn versucht wird, einen PropertyMock für eine Scheininstanz festzulegen (das Antwortmodell im obigen Beispiel). In diesem Fall müssen Sie PropertyMock auf das Typobjekt und nicht auf das Scheinobjekt selbst setzen.

Verwenden Sie PropertyMock für Eigenschaften(Erfolg)


>>> import requests
>>> from mock import patch, MagicMock, PropertyMock

>>> with patch('requests.Session'):
    s = requests.Session()
    response = MagicMock()
    text = PropertyMock()
    text.return_value = 'property'
    #Wenn Sie PropertyMock auf einen anderen Mock setzen, setzen Sie ihn auf dieses Objekt und nicht auf das Mock-Objekt selbst.
    type(response).text = text
    s.post.return_value = response
    print(s.post().text)
...
property

Ich habe bisher viel geschrieben

Beide wurden ordnungsgemäß in das Dokument geschrieben ...

http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch http://www.voidspace.org.uk/python/mock/mock.html?highlight=propertymock#mock.PropertyMock

Fazit

Lesen wir das Dokument richtig durch.

Recommended Posts

Ist es in Ordnung mit einem solchen Patch? (Memo über Mock ~ Part 2 ~)
Memo über Sphinx Teil 1 (Erstellen eines Projekts)
Ein Memo zum Erstellen einer Django (Python) -Anwendung mit Docker
Ein Memo, wenn mit Python + OpenCV schnell ein Gesicht erkannt wird
Ein Memorandum über den Python-Mock
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 4 sichtbar
Ein Memo für die Installation von pip3 mit python2.7 aus irgendeinem Grund
[Python] Was ist eine with-Anweisung?
Spiele mit einer Schildkröte mit Schildkrötengrafiken (Teil 1)
Ein Hinweis zu Mock (Python-Mock-Bibliothek)
Wenn Sie es so verwenden möchten, wie es ist, wenn Sie es mit Lambda-Memo verwenden
Erfahren Sie mehr über COM (Component Object Model) leise Teil 2 Ist es wirklich sprachunabhängig?