In diesem Satz
erklären. In Python3 ist MagicMock im Standardmodul unittest.mock enthalten. In Python2 können Sie es verwenden, indem Sie das Mock-Paket mit "pip install mock" installieren.
Starten Sie den Python-Interpreter und erstellen Sie ein MagicMock-Objekt
$ python3.6
Python 3.6.0 (default, Feb 27 2017, 00:03:01)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest.mock import MagicMock
>>> f = MagicMock()
Ich gehe davon aus, dass dieses f
eine Funktion ist und versuche es aufzurufen
>>> f(1)
<MagicMock name='mock()' id='4381867704'>
Ich kann es aufrufen, obwohl ich es nicht als Funktion definiert habe. Das ist seltsam. Der Rückgabewert ist ebenfalls MagicMock, aber das interessiert mich nicht und ich werde es weiter aufrufen
>>> f(2)
<MagicMock name='mock()' id='4381867704'>
>>> f(1, 2, 3)
<MagicMock name='mock()' id='4381867704'>
Ich könnte es frei nennen, selbst wenn ich den Wert des Arguments und die Anzahl der Argumente ändern würde. Ich bin überrascht. Wenn Sie versuchen, f.call_args_list
hier auszuwerten,
>>> f.call_args_list
[call(1), call(2), call(1, 2, 3)]
Ich habe es dreimal aufgerufen, seit ich MagicMock erstellt habe. Sie können sehen, dass es mit den Argumenten aufgezeichnet wird. Es ist interessant.
Dies ist nicht die einzige Funktion von MagicMock. Lassen Sie uns erneut eine MagicMock-Instanz erstellen, den Wert auf "f.return_value" setzen und dann "f" aufrufen.
>>> f = MagicMock()
>>> f.return_value = 5
>>> f(1, 2)
5
>>> f(1)
5
>>> f()
5
Unabhängig davon, welches Argument Sie angeben, wird der festgelegte Wert zurückgegeben. Auf diese Weise können Sie den Rückgabewert der Funktion durch einen beliebigen Wert ersetzen. Auch in diesem Fall wird aufgezeichnet, wie der Anruf getätigt wurde.
>>> f.call_args_list
[call(1, 2), call(1), call()]
Es gibt noch andere Funktionen, aber lassen wir dies zunächst weg und sehen, wie sie helfen können.
def push():
pass
def push_if_even(x):
"""()"""
if x % 2 == 0:
push()
from unittest.mock import MagicMock
push = MagicMock()
push_if_even(1)
assert len(push.call_args_list) == 0
push = MagicMock()
push_if_even(0)
assert len(push.call_args_list) == 1
print("success")
Insbesondere lautet der Code wie folgt. Nehmen Sie eine Ganzzahl und rufen Sie push auf, wenn es gerade ist. Angenommen, Sie möchten einen Test schreiben, um festzustellen, ob dieser Code korrekt implementiert ist. Wie wir bereits gesehen haben, zeichnet MagicMock auf, was als Funktion bezeichnet wurde, und nutzen dies aus. Sie können es folgendermaßen testen: Sie können auch wie folgt schreiben
push = MagicMock()
push_if_even(1)
push.asset_not_called()
push = MagicMock()
push_if_even(0)
push.assert_called_once()
Werfen wir einen Blick darauf, was passiert, wenn die Bestätigung fehlschlägt.
>>> from unittest.mock import MagicMock
>>> push = MagicMock()
>>> push.assert_called_once()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 795, in assert_called_once
raise AssertionError(msg)
AssertionError: Expected 'mock' to have been called once. Called 0 times.
>>> push()
<MagicMock name='mock()' id='4356157392'>
>>> push.assert_not_called()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 777, in assert_not_called
raise AssertionError(msg)
AssertionError: Expected 'mock' to not have been called. Called 1 times.
Eine Funktion, die True zurückgibt, wenn heute Sonntag ist, False andernfalls "is_sunday"
from datetime import date
def today():
return date.today()
def is_sunday():
return today().weekday() == 6
Angenommen, Sie möchten testen, ob dies ordnungsgemäß funktioniert. Wenn heute nicht Sonntag ist, können Sie es einmal aufrufen und sehen, dass es False zurückgibt. Warten Sie dann auf den nächsten Sonntag und rufen Sie es erneut auf, um zu sehen, dass es True zurückgibt. Es wird jedoch Tage dauern, bis der Test abgeschlossen ist. Wenn Sie nicht darauf warten können, können Sie mit MagicMock den Rückgabewert steuern.
from unittest.mock import MagicMock
today = MagicMock()
today.return_value = date(2020, 2, 1)
assert is_sunday() == False
today = MagicMock()
today.return_value = date(2020, 2, 2)
assert is_sunday() == True
print("success")
Wenn ja, können Sie es sofort testen. Es ist bequem.
Nachdem Sie die Natur von MagicMock gesehen haben,
Ich habe den Testcode mithilfe der Funktion von implementiert. Das Testen auf Funktionen, die sich auf die Umgebung auswirken oder von dieser beeinflusst werden, ist schwieriger zu schreiben als das Testen einfacher Funktionen. Sie können jedoch die Auswirkungen auf die Umgebung verspotten oder die Auswirkungen auf die Umgebung unterdrücken. Wir haben gesehen, dass es einfach ist, reproduzierbaren Testcode durch Ersetzen zu erstellen.
In diesem Beispiel habe ich die Funktion einfach überschrieben, aber das Mock-Modul verfügt über eine praktische Funktion namens Patch, mit der die Funktion nur während des Tests ersetzt und anschließend wiederhergestellt werden kann. Verwenden Sie es beim Schreiben von Tests.
Recommended Posts